How to parse whether a string is a valid US currency value - vb.net

Originally I was using
Decimal.TryParse(input, New Decimal)
to figure out of user input is valid money. This works for most cases, except I only want to accept money within 2 digits, so "10.001" should not be accepted.
I looked all over SO for this simple and I imagine common issue but could not find an answer.

Mark in the discussion solved this for me. Thanks! Here's the VB.net code for what I was looking for:
Dim regex As Regex = New Regex("[0-9]?[0-9]?(\.[0-9]?[0-9]$)")
Dim match As Match = regex.Match(input)
If Not match.Success Then

Related

VB expressions to help search through scraped data in UiPath

I have made a process that reads PDFs and scrapes their text in UiPath. I am struggling to come up with a regular expression that I can use to search for a PO Number. The text that comes from the scrape is fairly unstructured so my best bet is to search for a set of numbers that starts with a 'PO' with no space. For example, "PO1234567890". I will be setting a variable so the system knows that no PO number was found if the string doesn't come up with anything. Any reference material would be welcome as I am a beginner to VB. Thanks!
I have researched and cannot find a way to do the type of search I would like to do.
I expect to be able to search for a "PO1234567890" and no let something like "PO" save. So I somehow need to be able to search for "PO - two digits" and any numbers following without whitespace.
Just try the following:
Dim Regex As System.Text.RegularExpressions.Regex
Regex = New System.Text.RegularExpressions.Regex("PO[0-9]+")
Regex.Matches(SearchString)
The regex string PO[0-9]+ means:
PO followed by at least one number
if you want more digits for example 3... just use PO[0-9]{3}[0-9]* that means:
PO followed by three numbers and as numbers as it can match.
If you need help using regex matches just ask.
Hope it helps!

Regex match SQL values string with multiple rows and same number of columns

I tried to match the sql values string (0),(5),(12),... or (0,11),(122,33),(4,51),... or (0,121,12),(31,4,5),(26,227,38),... and so on with the regular expression
\(\s*\d+\s*(\s*,\s*\d+\s*)*\)(\s*,\s*\(\s*\d+\s*(\s*,\s*\d+\s*)*\))*
and it works. But...
How can I ensure that the regex does not match a values string like (0,12),(1,2,3),(56,7) with different number of columns?
Thanks in advance...
As i mentioned in comment to the question, the best way to check if input string is valid: contains the same count of numbers between brackets, is to use client side programm, but not clear SQL.
Implementation:
List<string> s = new List<string>(){
"(0),(5),(12)", "(0,11),(122,33),(4,51)",
"(0,121,12),(31,4,5),(26,227,38)","(0,12),(1,2,3),(56,7)"};
var qry = s.Select(a=>new
{
orig = a,
newst = a.Split(new string[]{"),(", "(", ")"},
StringSplitOptions.RemoveEmptyEntries)
})
.Select(a=>new
{
orig = a.orig,
isValid = (a.newst
.Sum(b=>b.Split(new char[]{','},
StringSplitOptions.RemoveEmptyEntries).Count()) %
a.newst.Count()) ==0
});
Result:
orig isValid
(0),(5),(12) True
(0,11),(122,33),(4,51) True
(0,121,12),(31,4,5),(26,227,38) True
(0,12),(1,2,3),(56,7) False
Note: The second Select statement gets the modulo of sum of comma instances and the count of items in string array returned by Split function. If the result isn't equal to zero, it means that input string is invalid.
I strongly believe there's a simplest way to achieve that, but - at this moment - i don't know how ;)
:(
Unless you add some more constraints, I don't think you can solve this problem only with regular expressions.
It isn't able to solve all of your string problems, just as it cannot be used to check that the opening and closing of brackets (like "((())()(()(())))") is invalid. That's a more complicated issue.
That's what I learnt in class :P If someone knows a way then that'd be sweet!
I'm sorry, I spent a bit of time looking into how we could turn this string into an array and do more work to it with SQL but built in functionality is lacking and the solution would end up being very hacky.
I'd recommend trying to handle this situation differently as large scale string computation isn't the best way to go if your database is to gradually fill up.
A combination of client and serverside validation can be used to help prevent bad data (like the ones with more numbers) from getting into the database.
If you need to keep those numbers then you could rework your schema to include some metadata which you can use in your queries, like how many numbers there are and whether it all matches nicely. This information can be computed inexpensively from your server and provided to the database.
Good luck!

CDec doesn't return the correct value

I make code that multiply all values of a DatagridView column. The code is working, but there's a problem. In particular, I've added this:
Return CDec(x.Cells("Quote").Value.ToString.Replace(",", "."))
That returns me the split value, for example, if I would have:
2,7 the correct value to return is: 2.7, but the code returns 27 and this is strange. I performed some trying, and if I delete the CDec like:
Return x.Cells("Quote").Value.ToString.Replace(",", ".")
The value returned is correct, but I've a contrast with this function:
Private Function MultiplyDecimals(ByVal sender As Decimal()) As Decimal
Dim Result As Decimal
If Not sender Is Nothing AndAlso Not sender.Length = 0 Then
Result = sender.Aggregate(Function(a, b) a * b)
End If
Return Result
End Function
That returns me 0 if I delete "As Decimal". So what's wrong?
UPDATE with possible solution:
Dim bles = x.Cells("Quote").Value.ToString.Replace(",", ".")
Dim key = Convert.ToDecimal(bles)
MessageBox.Show(key)
Return CDec(key)
Since it looks like you are also trying to manually convert from a different culture, you should use the .NET methods for this, rather than roll your own. You have two conversions going on: From one cultural number system to another and from string to a numeric type.
To convert a string like "2,7" which might be a French or Italian value:
Dim str As String = "2,7"
Dim decVal As Decimal
If Decimal.TryParse(str, NumberStyles.AllowDecimalPoint,
New CultureInfo("it-IT"), decVal) Then
' decVal has the value
Else
' Parse failed
End If
or:
Dim cult As New CultureInfo("fr-FR")
If Decimal.TryParse(str, NumberStyles.AllowDecimalPoint,
cult, decVal) Then ...
This can often work, but you might get an exception depending on the content:
Dim decVal As Decimal
Dim cult As New CultureInfo("fr-FR")
decVal = Convert.ToDecimal(str, cult)
Console.WriteLine(decVal.ToString)
Note: I am guessing at the culture of the data. Based on your recent, related question Google indicates "Nazione" is Italian, but data from/about Algeria might well be French Algerian.
CDec, like most of the legacy VB functions, is only equipped to work with the active culture settings. So, it will seem like it is "broken" in some cases:
Console.WriteLine(CDec("2.7")) ' --> 2.7D US/Can
Console.WriteLine(CDec("2,7")) ' --> 27D
Console.WriteLine(CDec("2,,7")) ' --> 27D
On a machine using French or Italian culture, the opposite will happen: "2.7" will come out 27, "2,7" to 2.7D, but "2,,7" will probably crash just like "2..7" would in the US/Can.
The reason for this behavior is that in US/Can, a comma looks like noise and CDec ignores it. A string with a single decimal-dot will convert, but a string with 2 is invalid. It would be the reverse for French where the comma is used: any number of dots look like noise, and only single decimal-comma format will parse.
It is all part of the reason no one included CDec in the solution: It is sub-optimal for any sort of cultural conversions. Manually removing or replacing decimal markers is even less optimal when there are methods designed to do that only when needed.
Since you have a string value, try Decimal.Parse() instead of CDec().
If that doesn't give you the result you expect, then either you're not handling the string that you think you are (in which case, try logging the exact string to a text file or similar so you can see exactly what you have), or the PC's culture settings are not what you think they are (it may be set to a culture that uses the comma, rather than a period, as the decimal separator), in which case try one of the Decimal.Parse() overloads that allows you to specify the culture, or perhaps even just remove the call to .Replace().

Strip first 2 characters and replace with another

This seems like quite a silly basic question but it seems something I have completely passed over in my knowledge.
Basically I have a string representing a phone number (0 being the area code): 0828889988
And would like to replace the first zero with a 27 (South African dialing code) as I am pretty sure it will always be so, my SMS api requires it in international format but I want the user to enter it in local format, so should be: 27828889988
Is there a line or two of code I can call to replace that first character with the two others?
As is - I can think around a workaround solution but as I am not sure of the direct syntax will be quite a few lines long.
Dim number as String = "0828889988"
number = "27" + number.SubString(1)
return number //returns "27828889988"

RegEx to get path of file, without domain

I'm new to regular expressions, and have no clue where to start, it's like a diff language to me. But I need one quick to accomplish a task.
I need to take
http://www.domain.com/folder1/folder2/file_path.txt
and get just
/folder1/folder2/file_path.txt
from it.
Thanks!
construct a URI object from it and one of the properties of it will have what you want.
I think that regex should work:
^http://.*?/(.*)$
(tested with Python)
Since VB.NET is in the tag for this question, I assume you have access at the server side to the Request object:
Dim instance As HttpRequest
Dim value As String
value = instance.Path
This should give you exactly what you asked for.
Edit: On second thought - you could be parsing URLs from some input string... in which case, regex will only help if you have a simple (regular) set of inputs:
Do you know all the possible domains? i.e. are "http://www.ABC.com" and "http://www.DEF.com" the only possible domains?
Then here:
Dim text As String = "http://www.ABC.com/folder1/folder2/file.txt"
Dim pattern As String = "(?:http://www.ABC.com|http://www.DEF.com)(.*)"
Dim r As Regex = new Regex(pattern, RegexOptions.IgnoreCase)
' Match the regular expression pattern against a text string.
Dim m As Match = r.Match(text)
Dim g as Group = m.Groups(2) 'Gives the string matched by the capturing parentheses
Supporting more protocols and making the protocol optional too.
((https?|ftp)://)?(.*?)/(.*)