tags:

views:

36

answers:

2

I've got 3 or 4 patterns that I'm comparing user input against and I need to figure out if the user input matches one of the patters and to return the match if it does.

Since the input is multiline, I'm passing each individual line like so:

    Dim strRawInput() As String = Split(txtInput.Text, vbCrLf)
    Dim strInput As String

    txtOutput.Text = ""

    For Each strInput In strRawInput
        strInput.Trim(vbCr, vbLf, Chr(32))
        Validation(strInput)
    Next

Then I have this to find matches:

Dim m As Match

For i = 0 To strValidator.Length - 1
    Dim r As New Regex(strValidator(i))
    m = r.Match(strInput)

    If m.Success Then
        txtOutput.Text = txtOutput.Text & "Success: " & m.ToString & vbCrLf
        Exit Sub 
    Else

    End If
Next
txtOutput.Text = txtOutput.Text & "Not this time" & vbCrLf

How can I do this more efficiently? Also, I added the Exit Sub there to avoid showing the "Not this time" message even after a match is found (if the match is with one of the later patterns in the array), but I'd like to find a better way of doing that too.

Thanks in advance.

+1  A: 

Rather than generating your Regexs in the loop, generate them one time at the startup of the application. So maybe something like:

Private Shared m_regexes As New List(Of Regex)
Shared Sub New()
    For Each v As String In strValidator
        m_regexes.Add(New Regex(v))
    Next
End Sub

And then you can change your other code to:

For Each r As Regex In m_regexes
    Dim m As Match = r.Match(strInput)
    If m.Success Then
        txtOutput.Text = txtOutput.Text & "Success: " & m.ToString & vbCrLf
        Exit Sub
    Else

    End If
Next

Regarding the Exit Sub, I think it's fine, You've discovered that it matches at least one pattern, so why continue to evaluate the rest. But if you don't like methods that can "return" in multiple places, you could just replace it with a Boolean and a Exit For as:

Dim found as Boolean = false 
For Each ...
     If IsMatch Then
          found = True
          Exit For
     End If
 Next

 If Found Then
       ....
 Else
       .....
 End If
ho1
Can I keep the m as Match declaration outside of the loop as well?
Radu
@Radu: Do you mean the actual `Dim`ing? If so, yes you can put that outside the loop, but since you're initializing it inside the loop I'm not sure it would be any faster. I just put it inside the loop since I like having any variable declarations as close as possible to their actual use.
ho1
Yes, I just figured that declaring it once, and assigning a value on each use would be faster than declaring and assigning on each loop.
Radu
@Radu: I'm fairly sure it doesn't make much difference (in most cases at least), but if you really need to squeeze all the performance out of it you'd probably have to measure it in your circumstances to make sure. This question http://stackoverflow.com/questions/407255/difference-between-declaring-variables-before-or-in-loop seems to indicate that it sometimes even can be faster if declared inside the loop, but that it depends on a lot of factors.
ho1
A: 

Hmm if that's the case then wouldn't this be even better?

For i = 0 To strValidator.Length - 1
    Dim r As New Regex(strValidator(i))
    Dim m As Match = r.Match(strInput)

    If m.Success Then
        txtOutput.Text = txtOutput.Text & "Success: " & m.ToString & vbCrLf
        Exit Sub 
    End If
Next
Radu