vb.net string contains only 4 digit numbers(or a year) - vb.net

how can i check if a string only contains 4 digit numbers ( or a year )
i tried this
Dim rgx As New Regex("^/d{4}")
Dim number As String = "0000"
Console.WriteLine(rgx.IsMatch(number)) // true
number = "000a"
Console.WriteLine(rgx.IsMatch(number)) // false
number = "000"
Console.WriteLine(rgx.IsMatch(number)) //false
number = "00000"
Console.WriteLine(rgx.IsMatch(number)) // true <<< :(
this returns false when its less than 4 or at characters but not at more than 4
thanks!

I actually wouldn't use a regex for this. The expression is deceptively simple (^\d{4}$), until you realize that you also need to evaluate that numeric value to determine a valid year range... unless you want years like 0013 or 9015. You're most likely going to want the value as an integer in the end, anyway. Given that, the best validation is probably just to actually try to convert it to an integer right off the bat:
Dim numbers() As String = {"0000", "000a", "000", "00000"}
For Each number As String In numbers
Dim n As Integer
If Integer.TryParse(number, n) AndAlso number.Length = 4 Then
'It's a number. Now look at other criteria
End If
Next

Use LINQ to check if All characters IsDigit:
Dim result As Boolean = ((Not number Is Nothing) AndAlso ((number.Length = 4) AndAlso number.All(Function(c) Char.IsDigit(c))))

You should use the .NET string manipulation functions.
Firstly the requirements, the string must:
Contain exactly four characters, no more, no less;
Must consist of a numeric value
However your aim is to validate a Date:
Function isKnownGoodDate(ByVal input As String) As Boolean 'Define the function and its return value.
Try 'Try..Catch statement (error handling). Means an input with a space (for example ` ` won't cause a crash)
If (IsNumeric(input)) Then 'Checks if the input is a number
If (input.Length = 4) Then
Dim MyDate As String = "#01/01/" + input + "#"
If (IsDate(MyDate)) Then
Return True
End If
End If
End If
Catch
Return False
End Try
End Function
You may experience a warning:
Function isKnownGoodDate does not return a value on all code
paths. Are you missing a Return statement?
this can be safely ignored.

Related

Can a range of negative and positive numbers be used to pattern match using Like in vb.net

I have a user entered string:
"{0.3064, 15.6497, 60.7668, 52.1362, 76.6645, 97, -15.8315, -6.8806, 5.547, -2.3381, -23.9905, 40.4569, 60.1592, 27.1418, 42.9375, -22.8297, -11.7423, -17.1576, -33.9918, 7.0585}"
and I would like to be able to validate it based on having a "{" at the start, a "}" at the end and twenty comma separated numbers between -1000 and 1000 in between the commas.
I have tried using the like operator as below with no luck. Everything returns False no matter whether it matches the patter or not. How can I validate based on this pattern.
This is what I have tried:
ArrayOk = ArrayValues1txt.Text Like "{[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000],[(1000)-1000]}"
If ArrayOk = False Then
MsgBox("Wrong array pattern! Pattern must contain 20 elements and be in the form {#,#}",
MessageBoxButtons.OK, "Bad Array Entered")
GoTo Canceller
Else
End If
You can use RegEx to validate the general pattern of: Are there 20 decimal values separated by commas wrapped in curly brackets?
Dim pattern = "^{((-?\d+(\.\d+)?),\s?){19}(-?\d+(\.\d+)?)}$"
Dim input = "{0.3064, 15.6497, 60.7668, 52.1362, 76.6645, 97, -15.8315, -6.8806, 5.547, -2.3381, -23.9905, 40.4569, 60.1592, 27.1418, 42.9375, -22.8297, -11.7423, -17.1576, -33.9918, 7.0585}"
If (Regex.IsMatch(input, pattern)) Then
End If
Once you validated that it matches the specific pattern, you can validate that the numbers match the numeric range validation by doing the following:
Remove the brackets from the String
Split the string by a comma
Trim any excessive whitespace from the items
Convert the items to fractional values (Double, Decimal, etc.)
Check if the items are within range
You can do a lot of those steps using LINQ which would make it much more concise:
Dim pattern = "^{((-?\d+(\.\d+)?),\s?){19}(-?\d+(\.\d+)?)}$"
Dim input = "{0.3064, 15.6497, 60.7668, 52.1362, 76.6645, 97, -15.8315, -6.8806, 5.547, -2.3381, -23.9905, 40.4569, 60.1592, 27.1418, 42.9375, -22.8297, -11.7423, -17.1576, -33.9918, 7.0585}"
If (Regex.IsMatch(input, pattern)) Then
input = input.Replace("{", String.Empty).Replace("}", String.Empty)
Dim items = input.Split(",")
Dim convertedItems = items.Select(Function(item) Convert.ToDouble(item.Trim())).ToArray()
If (convertedItems.All(Function(item) item >= -1000 AndAlso item <= 1000)) Then
Console.WriteLine("All of the items are within -1000 and 1000")
End If
End If
Here is a live demo: fiddle
I used String.StartsWith and String.EndsWith to test for the braces. Next I chopped them off with Substring. I then split the string by commas. I checked whether there were exactly 20 elements.
If we get this far, I loop through each element. Trim off any leading or trailing spaces and change it to a double. Then I can do the number comparison.
Private Function ValidateArray(input As String) As Boolean
If Not input.StartsWith("{") OrElse Not input.EndsWith("}") Then
Return False
End If
input = input.Substring(1, input.Length - 2)
Dim splits = input.Split(","c)
If splits.Length <> 20 Then
Return False
End If
For Each n In splits
Dim dbl = CDbl(n.Trim)
If dbl > 1000 OrElse dbl < -1000 Then
Return False
End If
Next
Return True
End Function
Usage:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim IsValid = ValidateArray("{0.3064, 15.6497, 60.7668, 52.1362, 76.6645, 97, -15.8315, -6.8806, 5.547, -2.3381, -23.9905, 40.4569, 60.1592, 27.1418, 42.9375, -22.8297, -11.7423, -17.1576, -33.9918, 7.0585}")
MessageBox.Show(IsValid.ToString)
End Sub

increment alphanumeric string where alphabet position in a string is keeps changing

I need to save Multiple(about 20-25) serial number of the specimen in my application. Sometimes serial number will be alphanumeric but will be sequential. I need a way out to increment alphanumeric serial numbers based on the first serial number entered.
My main problem is alphabet position and alphabet count keeps changing. Example : 10MG2015 20562MG0 MGX02526 etc etc
I tried but mine works when Alphabet are in starting position and when there are known number of alphabets. Here is my try
Dim intValue as integer
Dim serialno as string
Dim serialno1 as string
For i =0 to 20
Serialno1 = serialno.Substring(3)
Int32.TryParse(Serialno1, intValue)
intValue = intValue + 1
checkedox1.items.add(serialno.Substring(0,3) + intValue.ToString("D3"))
NEXT
Any help is highly appreciated. Thanks in advance
edit 1
Clarity : I want to increment alphanumeric string. Example : If first entered one is 10MG2015 then I should increment to 10MG2016, 10MG2017, 10MG2018, 10MG2019 and so on... For 20562MG0 it will be 20562MG1, 20562MG2 20562MG3 and so on...
Function FindSequenceNumber(SerialNumber As String) As Integer
'Look for at least four digits in a row, and capture all the digits
Dim sequenceExpr As New Regex("([0-9]{4,11})")
Dim result As Integer = -1
Dim m As Match = sequenceExpr.Match(SerialNumber)
If m.Success AndAlso Integer.TryParse(m.Groups(1).Value, result) Then
Return result
Else
'Throw exception, return -1, etc
End If
End Function
See it here:
https://dotnetfiddle.net/gO2nue
Note: the integer type doesn't preserve leading zeros. You may find it better to return a tuple with either the length of the original string, so you can pad zeros to the left if needed to match the original formatting.
Or maybe this:
Function IncrementSerial(SerialNumber As String) As String
'Look for at least four digits in a row, and capture all the digits
Dim sequenceExpr As New Regex("([0-9]{4,11})")
Dim m As Match = sequenceExpr.Match(SerialNumber)
If Not m.Success Then Throw New Exception("No sequence number found")
Dim c = m.Groups(1).Captures(0)
Dim seq = (Integer.Parse(c.Value) + 1).ToString()
If seq.Length < c.Value.Length Then
seq = seq.PadLeft(c.Value.Length, "0"c)
End If
Dim result As String = ""
If c.Index > 0 Then result & = SerialNumber.Substring(0, c.Index)
result &= seq
If c.Index + seq.Length < SerialNumber.Length Then result &= SerialNumber.SubString(c.Index + seq.Length)
Return result
End Function

Reading only first 1 to 2 integers in a for loop VBA

How do I read the first 1 to 2 integers of a string in a loop? I need to only parse the first integer or the second integer. For example, "8sdr" I only want to parse "8" and then for a "12sdr" I want to parse "12". I need this to be in a loop to be able to continuously parse only the first integers in a string. Thank you!
The following will return any given number of digits from the start of a string:
Function LeadingDigits(text As String, maxDigits As Integer) As String
Dim pos As Integer, c As String
Do Until pos >= maxDigits Or pos >= Len(text)
c = Mid$(text, pos + 1, 1)
If c < "0" Or c > "9" Then Exit Do
pos = pos + 1
Loop
LeadingDigits = Mid$(text, 1, pos)
End Function
Contrary to solutions that rely on IsNumeric() or Val(), this function does not get confused by strings that can be interpreted as numeric, but don't fall into the specification, such as
hexadecimal ("&habc" = 2748)
scientific notation ("3e4" = 30000)
+/- signs at the start of the string
decimal numbers ".5" = 0.5
Only decimal digits 0–9 at the start of the string are accepted.
The function returns a string, not a numeric type (like Integer) so that there can be a separate return value for "nothing found" (the empty string), and so that very long numbers can be returned that would not fit into a numeric data type.
If you need only up to two numbers that occur before a letter I would use RegEx for this:
Public Function FirstTwoNumbersFromStringBeforeLetter(ByVal textNumbers As String) As Long
Dim regEx
Set regEx = CreateObject("vbscript.regexp")
With regEx
.Global = True
.Pattern = "[a-z].*|\D"
FirstTwoNumbersFromStringBeforeLetter = Left(Val(.Replace(textNumbers, vbNullString)), 2)
End With
End Function

How to increase numeric value present in a string

I'm using this query in vb.net
Raw_data = Alltext_line.Substring(Alltext_line.IndexOf("R|1"))
and I want to increase R|1 to R|2, R|3 and so on using for loop.
I tried it many ways but getting error
string to double is invalid
any help will be appreciated
You must first extract the number from the string. If the text part ("R") is always separated from the number part by a "|", you can easily separated the two with Split:
Dim Alltext_line = "R|1"
Dim parts = Alltext_line.Split("|"c)
parts is a string array. If this results in two parts, the string has the expected shape and we can try to convert the second part to a number, increase it and then re-create the string using the increased number
Dim n As Integer
If parts.Length = 2 AndAlso Integer.TryParse(parts(1), n) Then
Alltext_line = parts(0) & "|" & (n + 1)
End If
Note that the c in "|"c denotes a Char constant in VB.
An alternate solution that takes advantage of the String type defined as an Array of Chars.
I'm using string.Concat() to patch together the resulting IEnumerable(Of Char) and CInt() to convert the string to an Integer and sum 1 to its value.
Raw_data = "R|151"
Dim Result As String = Raw_data.Substring(0, 2) & (CInt(String.Concat(Raw_data.Skip(2))) + 1).ToString
This, of course, supposes that the source string is directly convertible to an Integer type.
If a value check is instead required, you can use Integer.TryParse() to perform the validation:
Dim ValuePart As String = Raw_data.Substring(2)
Dim Value As Integer = 0
If Integer.TryParse(ValuePart, Value) Then
Raw_data = Raw_data.Substring(0, 2) & (Value + 1).ToString
End If
If the left part can be variable (in size or content), the answer provided by Olivier Jacot-Descombes is covering this scenario already.
Sub IncrVal()
Dim s = "R|1"
For x% = 1 To 10
s = Regex.Replace(s, "[0-9]+", Function(m) Integer.Parse(m.Value) + 1)
Next
End Sub

Visual basic palindrome code

I am trying to create an application which will determine whether a string entered by user is a palindrome or not.
Is it possible to do without StrReverse, possibly with for next loop. That's what i have done so far.
Working one, with StrReverse:
Dim userInput As String = Me.txtbx1.Text.Trim.Replace(" ", "")
Dim toBeComparedWith As String = StrReverse(userInput)
Select Case String.Compare(userInput, toBeComparedWith, True)
Case 0
Me.lbl2.Text = "The following string is a palindrom"
Case Else
Me.lbl2.Text = "The following string is not a palindrom"
End Select
Not working one:
Dim input As String = TextBox1.Text.Trim.Replace(" ", "")
Dim pallindromeChecker As String = input
Dim output As String
For counter As Integer = input To pallindromeChecker Step -1
output = pallindromeChecker
Next counter
output = pallindromeChecker
If output = input Then
Me.Label1.Text = "output"
Else
Me.Label1.Text = "hi"
End If
While using string reversal works, it is suboptimal because you're iterating over the string at least 2 full times (as string reversal creates a copy of a string because strings are immutable in .NET) (plus extra iterations for your Trim and Replace calls).
However consider the essential properties of a palindrome: the first half of a string is equal to the second half of the string in reverse.
The optimal algorithm for checking a palindrome needs only iterate through half of the input string - by comparing value[n] with value[length-n] for n = 0 to length/2.
In VB.NET:
Public Shared Function IsPalindrome(value As String) As Boolean
' Input validation.
If value Is Nothing Then Throw New ArgumentNullException("value")
value = value.Replace(" ", "") // Note String.Replace(String,String) runs in O(n) time and if replacement is necessary then O(n) space.
' Shortcut case if the input string is empty.
If value.Length = 0 Then Return False ' or True, depends on your preference
' Only need to iterate until half of the string length.
' Note that integer division results in a truncated value, e.g. (5 / 2 = 2)...
'... so this ignores the middle character if the string is an odd-number of characters long.
Dim max As Integer = value.Length - 1
For i As Integer = 0 To value.Length / 2
If value(i) <> value(max-i) Then
' Shortcut: we can abort on the first mismatched character we encounter, no need to check further.
Return False
End If
Next i
' All "opposite" characters are equal, so return True.
Return True
End Function