Search code examples
stringvb.netsplit

How do I parse a string with both letters and integers into string and integer variables in VB.net?


I am reading strings from a file. Each string will have a string component followed by 2 integer components separated by a hash.

String Examples: "A1-8" "AN9-16" "OUT16-24" "CARD32-40"

Is there a simple way to parse these into a string variable and 2 integer variables? for example with "AN9-16" I want to get

StrVar = "AN"
IntVar1 = 9
IntVar2 = 16

Thanks in advance.

I haven't really tried anything so far. I considered looking at each char in the string and then splitting it with the first integer and then with the hash, but that seems over complicated.


Solution

  • Here's a simple solution that shows you how you can "walk through" your string one character at a time to find the delimitations. You can use IsNumeric to determine where the text part ends. Then with that position, use Substring to separate both parts. Finally, use Split to separate the numeric part on the "-":

    Sub ParseString(value As String)
        Dim position As Integer = 0
    
        ' Find all non-numeric characters
        Do While Not IsNumeric(value.Substring(position, 1))
            position += 1
        Loop
    
        ' Extract text part 
        Dim textPart As String = value.Substring(0, position)
    
        ' Extract numeric part
        Dim numericPart As String = value.Substring(position + 1)
    
        ' Split numeric part on -
        Dim numericValues As String() = Strings.Split(numericPart, "-")
    
        MsgBox("Text part: " & textPart & vbCrLf & "First numeric value: " & numericValues(0) & vbCrLf & "Second numeric value: " & numericValues(1))
    
    End Sub
    

    This is a primitive way to do things and will fail if your string is not in the format you have described. Nonetheless, it demonstrates how you can break a problem down into easier parts to solve.


    Going further, you can define a class to return the values from your string:

    Public Class ItemCode
    
        Public Property StringValue As String
        Public Property IntegerValue1 As Integer
        Public Property IntegerValue2 As Integer
    
        ''' <summary>
        ''' Creates a new instance of the <see cref="ItemCode"/> class.
        ''' </summary>
        Public Sub New()
        End Sub
    
        ''' <summary>
        ''' Creates a new instance of the <see cref="ItemCode"/> class.
        ''' </summary>
        ''' <param name="stringValue"></param>
        ''' <param name="integerValue1"></param>
        ''' <param name="integerValue2"></param>
        Public Sub New(stringValue As String, integerValue1 As Integer, integerValue2 As Integer)
            Me.StringValue = stringValue
            Me.IntegerValue1 = integerValue1
            Me.IntegerValue2 = integerValue2
        End Sub
    
    End Class
    

    You can use this class as the return value for your parsing function. Here's a version that uses Regular Expressions, using a pattern with subexpressions that that collects the matches in 4 Groups (Groups 1, 2 and 3 contain your values, or empty strings where there's no match):

    Public Function GetItemCodeUsingRegEx(value As String) As ItemCode
        Dim regEx As New Regex("(\D+)(\d*)-(\d+)")
        Dim matchCollection As MatchCollection = regEx.Matches(value)
        Return New ItemCode(matchCollection(0).Groups(1).Value, CInt(matchCollection(0).Groups(2).Value), CInt(matchCollection(0).Groups(3).Value))
    End Function
    

    Finally, updating my original answer with this new class:

    Public Function GetItemCode(value As String) As ItemCode
        Dim position As Integer = 0
    
        ' Find all non-numeric characters
        Do While Not IsNumeric(value.Substring(position, 1))
            position += 1
        Loop
    
        ' Extract text part 
        Dim textPart As String = value.Substring(0, position)
    
        ' Extract numeric part
        Dim numericPart As String = value.Substring(position + 1)
    
        ' Split numeric part on -
        Dim numericValues As String() = Strings.Split(numericPart, "-")
    
        Return New ItemCode(textPart, CInt(numericValues(0)), CInt(numericValues(1)))
    
    End Function