Bug? Matcher.Find is reset once first examined.

RandomCoder

Well-Known Member
Licensed User
Longtime User
Whilst trying to debug some code that uses RegEx, I've found that once you have examined if a match was found, it reset the state. In the example below a match is always found with the values I send and the log displays "A" but never displays "B, C or D" and so with the last statement I always return an empty string. This is the case in Debug mode AND in release mode.
I only found it by chance because I was adding additional log statements in to record what each group had found and I ended up breaking my code. With a little fault finding I worked out that the m.find state is everting to false after the first call.
B4X:
Public Sub Extract( strPattern As String, strText As String, blnCaseSensitive As Boolean, intExtractGroup As Int) As String
    Dim m As Matcher
    If blnCaseSensitive Then
        m = Regex.Matcher(strPattern, strText)       
    Else
        m = Regex.Matcher2(strPattern, Regex.CASE_INSENSITIVE, strText)
    End If
    Log(m.GroupCount)
    If m.Find = True Then Log("A")
    If m.Find = True Then Log("B")
    If m.Find = True Then Log("C")
    If m.Find = True Then Log("D")
    If m.Find = True Then Return m.Group(intExtractGroup)
    ' Return an empty string if pattern not found
    Return ""
End Sub
 

RandomCoder

Well-Known Member
Licensed User
Longtime User
Attached a simple example (taken from a code sample here on the forum)...
B4X:
#Region  Service Attributes
    #StartAtBoot: False
    #ExcludeFromLibrary: True
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Service_Create
    'This is the program entry point.
    'This is a good place to load resources that are not specific to a single activity.

End Sub

Sub Service_Start (StartingIntent As Intent)
    Log("Valid email format = " & Validate_Email("Hewlett-Packard@HPforyou.hp.com"))
End Sub

'Return true to allow the OS default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    Return True
End Sub

Sub Service_Destroy

End Sub

Sub Validate_Email(EmailAddress As String) As Boolean
    Dim MatchEmail As Matcher = Regex.Matcher("^(?i)[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])$", EmailAddress)

    Log("Status=" & MatchEmail.Find)
    If MatchEmail.Find = True Then
        Log(MatchEmail.Match)
        Return True
    Else
        Log("Oops, please double check your email address...")
        Return False
    End If
End Sub
I suppose normally you would only check the find property once and so this could have easily gone unnoticed...
"LogCat connected to: 07795cb8
--------- beginning of crash
--------- beginning of system
--------- beginning of main
** Service (starter) Create **
** Service (starter) Start **
Status=true
Oops, please double check your email address...
Valid email format = false
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **"
 

Attachments

  • MatcherTest.zip
    6.8 KB · Views: 211

RandomCoder

Well-Known Member
Licensed User
Longtime User
I should have realised that it would be my mistake, I hadn't realised that calling matcher.find triggered a search for another match and returned true or false again depending on if one was found. I was going through some old code and mistakenly thought that the Regex.Matcher instruction was what did the search, now I see that it only sets the pattern and matcher.find executes the search.
Sorry to have wasted your time and I thank you for putting me back on the right path.

Kind regards,
RandomCoder.
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…