homelinksBlijf op de hoogte van de recente aanpassingen op vbvoorbeelden!
Visual Basic 2010 Voorbeelden

visual basic 2010 broncode voorbeelden

Microsoft Visual Studio 2010Microsoft Developers Network - Visual BasicMicrosoft .NET Framework

27.8. Regular Expressions - Class Quantifiers

Print Email Deel op Facebook Deel op Twitter

Dit artikel is gepubliceerd op zondag 31 juli 2011 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.

27.8.1. Exacte Multipliciteit

Indien een bepaald token ( karakter, character class, group, ... ) een aantal keer kan voorkomen, kan men deze multipliciteit tussen accolades weergeven.

Dit gebeurt in de vorm {min,max}, het ,max gedeelte is optioneel.
Visual Basic 2010 Broncode
Imports System.Text.RegularExpressions
Class Example1
    Public Shared Sub Main()
        ' Any text with 2 characters a :
        Example1.Print("abaa", "a{2}") ' matches "aa" at index 2
        '
        ' Any text ( length 1 or more ) containing characters a :
        Example1.Print("abaa", "a{1,}") ' matches "a" at index 0
        '                                 matches "aa" at index 2
        '
        ' Any text ( length 1 or 2 ) containing characters a :
        Example1.Print("abaa", "a{1,2}") ' matches "a" at index 0
        '                                  matches "aa" at index 2
        '
        Console.ReadLine()
    End Sub
    Public Shared Sub Print(ByVal input As String, ByVal pattern As String)
        Dim r As Regex = New Regex(pattern)
        Dim m As Match = r.Match(input)
        If m.Success Then
            Do
                Console.WriteLine("""" & input & """ has" & _
                                  " match """ & m.Value & """ " & _
                                  "at index " & m.Index.ToString() & _
                                  " for pattern """ & pattern & """")
                m = m.NextMatch()
            Loop While m.Success
        Else
            Console.Write("""" & input & """ has no match" & _
                          " for pattern """ & pattern & """")
        End If
    End Sub
End Class
Console Application Output
"abaa" has match "aa" at index 2 for pattern "a{2}"
"abaa" has match "a" at index 0 for pattern "a{1,}"
"abaa" has match "aa" at index 2 for pattern "a{1,}"
"abaa" has match "a" at index 0 for pattern "a{1,2}"
"abaa" has match "aa" at index 2 for pattern "a{1,2}"

27.8.2. Wildcards of Jokertekens

Door jokertekens als *, ? en + te gebruiken kan men aangeven hoe vaak een token ( karakter, character class, group, ... ) mag voorkomen in het zoekresultaat.

? staat voor 0 of 1, en is gelijk aan {0,1}.
* staat voor 0 of meerdere, en is gelijk aan {0,}.
+ staat voor 1 of meerdere, en is gelijk aan {1,}.
Visual Basic 2010 Broncode
Imports System.Text.RegularExpressions
Class Example2
    Public Shared Sub Main()
        ' Any text ( length 1 or more ) where character b is followed by as
        ' many as possible characters c :
        Example1.Print("babcc", "bc*") ' matches "b" at index 0
        '                                matches "bcc" at index 2
        '
        ' Any text ( length 2 or more ) where character b is followed by as
        ' many as possible ( at least 1 ) characters c :
        Example1.Print("babcc", "bc+") ' matches "bcc" at index 2
        '
        ' Any text ( length 1 or 2 ) where character b is possibly
        ' followed by character c :
        Example1.Print("babcc", "bc?") ' matches "b" at index 0
        '                                matches "bc" at index 2
        Console.ReadLine()
    End Sub
End Class
Console Application Output
"babcc" has match "b" at index 0 for pattern "bc*"
"babcc" has match "bcc" at index 2 for pattern "bc*"
"babcc" has match "bcc" at index 2 for pattern "bc+"
"babcc" has match "b" at index 0 for pattern "bc?"
"babcc" has match "bc" at index 2 for pattern "bc?"

27.8.3. Eager Regex Engine

Stel dat we op zoek gaan naar de tekst "cat" of "cats" in de inputstring "cats love the catwalk", dan wensen we de tekst "cats" op index 0 en "cat" op index 14 terug te vinden.
Dit is echter niet het geval bij onderstaande pattern op regel (1).  Daar wordt in plaats van "cats" op index 0, de tekst "cat" op index 0 gevonden.
Dit is veroorzaakt doordat de regex engine eager was om de eerste optie te gebruiken voor de eerste match.
Een oplossing kan eruit bestaan de opties om te wisselen (2) of via een ? na s (3), waardoor deze 0 of 1 keer mag voorkomen.  ? is "greedy" genoeg om meteen te proberen "cat" met daarop volgend een "s" te vinden.
Visual Basic 2010 Broncode
Imports System.Text.RegularExpressions
Class Example3
    Public Shared Sub Main()
        Dim input As String = "cats love the catwalk"
        Example1.Print(input, "cat|cats") ' matches "cat" at index 0 and     (1)
        '                                   "cat" at index 14
        Example1.Print(input, "cats|cat") ' matches "cats" at index 0 and    (2)
        '                                   "cat" at index 14
        Example1.Print(input, "cats?")    ' matches "cats" at index 0 and    (3)
        '                                   "cat" at index 14
        '
        Console.ReadLine()
    End Sub
End Class
Console Application Output
"cats love the catwalk" has match "cat" at index 0 for pattern "cat|cats"
"cats love the catwalk" has match "cat" at index 14 for pattern "cat|cats"
"cats love the catwalk" has match "cats" at index 0 for pattern "cats|cat"
"cats love the catwalk" has match "cat" at index 14 for pattern "cats|cat"
"cats love the catwalk" has match "cats" at index 0 for pattern "cats?"
"cats love the catwalk" has match "cat" at index 14 for pattern "cats?"

27.8.4. Greedy Class Quantifiers

Als we op de HTML-string "This is important." het pattern <.+> los zouden laten (1), met als bedoeling de eerst HTML-tag ( "" ) te vinden, krijgen we niet het gewenste effect.  Het resultaat is "important".

.+ probeert immers zo veel mogelijk karakters te vinden voor een matching ">".  De regex engine merkt dat het deelpattern <.+ alvast matched met de tekst "important.", maar omdat de daarop volgende > uit het pattern niet matcht met de void na de match die tot dan toe werd gevonden, zal de engine backtracking toepassen tot de positie waarop het volgend karakter op de deelmacht een ">" is.

De quantifiers +, * en ? zijn wat men noemt "greedy", en proberen dus zo veel mogelijk op te nemen in de match.

Om de quantifiers "reluctant" ( "ungreedy" ) te maken, kan men een ? plaatsen, na deze quantifier (2).
Visual Basic 2010 Broncode
Imports System.Text.RegularExpressions
Class Example4
    Public Shared Sub Main()
        Dim input As String = "This is <b>important</b>."
        Example1.Print(input, "<.+>")    ' matches with "<b>important</b>"   (1)
        Example1.Print(input, "<.+?>")   ' matches with "<b>" and "</b>"     (2)
        Example1.Print(input, "<[^>]+>") ' matches with "<b>" and "</b>"     (3)
        '
        Console.ReadLine()
    End Sub
End Class
Console Application Output
"This is <b>important</b>." has match "<b>important</b>" at index 8 for pattern
"<.+>"
"This is <b>important</b>." has match "<b>" at index 8 for pattern "<.+?>"
"This is <b>important</b>." has match "</b>" at index 20 for pattern "<.+?>"
"This is <b>important</b>." has match "<b>" at index 8 for pattern "<[^>]+>"
"This is <b>important</b>." has match "</b>" at index 20 for pattern "<[^>]+>"
Ook pattern op regel (3) die gebruik maakt van een negative character group kan hier de oplossing vormen.

In onderstaand voorbeeld zie je hoe ? de voorkeur zal geven aan een match waarbij toch het optionele token gevonden is (1).

Een ? plaatsen na de vorige ? (2) maakt deze "reluctant" ( "ungreedy" ).
Visual Basic 2010 Broncode
Imports System.Text.RegularExpressions
Class Example5
    Public Shared Sub Main()
        Dim input As String
        input = "March 3rd"
        '
        Example1.Print(input, "March 3(rd)?")  ' matches "March 3rd"         (1)
        Example1.Print(input, "March 3(rd)??") ' matches "March 3"           (2)
        '
        Console.ReadLine()
    End Sub
End Class
Console Application Output
"March 3rd" has match "March 3rd" at index 0 for pattern "March 3(rd)?"
"March 3rd" has match "March 3" at index 0 for pattern "March 3(rd)??"
Al heeft dat natuurlijk weinig nut want pattern March 3(rd)?? zal altijd hetzelfde vinden als pattern March 3.

Dit artikel is gepubliceerd op zondag 31 juli 2011 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.