Megosztás a következőn keresztül:


Kvantitátorok reguláris kifejezésekben

A kvantátorok megadják, hogy egy karakter, csoport vagy karakterosztály hány példányának kell szerepelnie a bemenetben ahhoz, hogy egy egyezést találjon. Az alábbi táblázat a .NET által támogatott kvantitátorokat sorolja fel:

Mohó kvantáló Lusta kvantor Leírás
* *? Nulla vagy több alkalommal fordul elő.
+ +? Egy vagy több alkalommal egyezést talál.
? ?? Nullaszor vagy egyszer egyezik meg.
{ n} { n}? Pontosan n-szer egyezik.
{ n,} { n,}? Legalább n-szer megegyezik.
{ n,m} { n,m}? N és m közötti egyezések.

A mennyiségek n és m egész számállandók. A kvantitátorok általában kapzsiak. Ezek hatására a normál kifejezésmotor a lehető legtöbb előfordulásnak felel meg az adott mintákban. Ha hozzáfűzi a ? karaktert egy kvantálóhoz, az lusta lesz. Ez azt eredményezi, hogy a normál kifejezésmotor a lehető legkevesebb előfordulásnak felel meg. A mohó és a lusta kvantorok közötti különbség teljes leírását a jelen cikk későbbi, Mohó és lusta kvantorok című szakaszában találja.

Fontos

A kvantátorok, például a reguláris kifejezésminta (a*)*beágyazása növelheti a reguláris kifejezésmotor által végrehajtandó összehasonlítások számát. Az összehasonlítások száma a bemeneti sztringben szereplő karakterek számának exponenciális függvényeként nőhet. Erről a viselkedésről és a kerülő megoldásokról további információt a Visszakövetés című témakörben talál.

Reguláris kifejezés mennyiségi operátorok

Az alábbi szakaszok felsorolják a .NET-reguláris kifejezések által támogatott kvantitátorokat:

Feljegyzés

Ha a *, +, ?, {és } karakterek egy reguláris kifejezési mintában jelennek meg, a reguláris kifejezésmotor kvantitátorként vagy kvantitátor-szerkezetek részeként értelmezi őket, kivéve, ha egy karakterosztály tartalmazza őket. Ha ezeket egy karakterosztályon kívüli literális karakterként szeretné értelmezni, el kell őket menekülnie, ha fordított perjellel előzi meg őket. A reguláris kifejezésmintában például a karakterlánc \* szó szerinti csillag ("*") karakterként van értelmezve.

Nulla vagy több időpont egyeztetése: *

A * kvantáló megegyezik az előző nullával vagy több alkalommal. Egyenértékű a kvantálóval {0,} . * egy kapzsi kvantor, amelynek lusta megfelelője *?.

Az alábbi példa ezt a reguláris kifejezést szemlélteti. A bemeneti sztring kilenc számjegycsoportja közül öt egyezik a mintával, és négy (95, 929, 9219és 9919) nem.

string pattern = @"\b91*9*\b";
string input = "99 95 919 929 9119 9219 999 9919 91119";
foreach (Match match in Regex.Matches(input, pattern))
   Console.WriteLine($"'{match.Value}' found at position {match.Index}.");

// The example displays the following output:
//       '99' found at position 0.
//       '919' found at position 6.
//       '9119' found at position 14.
//       '999' found at position 24.
//       '91119' found at position 33.
Dim pattern As String = "\b91*9*\b"
Dim input As String = "99 95 919 929 9119 9219 999 9919 91119"
For Each match As Match In Regex.Matches(input, pattern)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'       '99' found at position 0.
'       '919' found at position 6.
'       '9119' found at position 14.
'       '999' found at position 24.
'       '91119' found at position 33.

A reguláris kifejezésminta a következő táblázatban látható módon van definiálva:

Minta Leírás
\b Meghatározza, hogy az egyezésnek egy szóhatáron kell kezdődnie.
91* Egy 9-t követő, nulla vagy több 1 karakterrel egyező mintát határoz meg.
9* Megfelel nulla vagy több 9 karakternek.
\b Meghatározza, hogy az egyezésnek egy szóhatáron kell végződnie.

Egy vagy több időpont egyeztetése: +

A + kvantáló egy vagy több alkalommal felel meg az előző elemnek. Ez egyenértékű a {1,}. + egy kapzsi kvantor, amelynek lusta megfelelője +?.

A reguláris kifejezés \ban+\w*?\b például megpróbál egyezni az olyan teljes szavakkal, amelyek a betűvel a kezdődnek, és amelyeket a betű n egy vagy több példánya követ. Az alábbi példa ezt a reguláris kifejezést szemlélteti. A reguláris kifejezés illeszkedik a szavakhoz an, annual, announcement, és antique, és helyesen nem illeszkedik autumn és all.

string pattern = @"\ban+\w*?\b";

string input = "Autumn is a great time for an annual announcement to all antique collectors.";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
   Console.WriteLine($"'{match.Value}' found at position {match.Index}.");

// The example displays the following output:
//       'an' found at position 27.
//       'annual' found at position 30.
//       'announcement' found at position 37.
//       'antique' found at position 57.
Dim pattern As String = "\ban+\w*?\b"

Dim input As String = "Autumn is a great time for an annual announcement to all antique collectors."
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'       'an' found at position 27.
'       'annual' found at position 30.
'       'announcement' found at position 37.
'       'antique' found at position 57.

A reguláris kifejezésminta a következő táblázatban látható módon van definiálva:

Minta Leírás
\b Kezdje egy szóhatáron.
an+ Az a elemet, amelyet egy vagy több n karakter követ, egyezik.
\w*? Egy szókaraktert nullától többször egyeztet, de a lehető legkevesebbszer.
\b Egy szóhatáron végződik.

Nulla vagy egyszeri találat: ?

A ? kvantor az előző elemet nulla vagy egyszer illeszti. Ez egyenértékű a {0,1}. ? egy kapzsi kvantor, amelynek lusta megfelelője ??.

A reguláris kifejezés \ban?\b például megpróbál egyezést találni az olyan teljes szavakkal, amelyek a a betűvel kezdődnek, és amelyeket a(z) n betű nulla vagy egy példánya követ. Másként fogalmazva, megpróbálja összeilleszteni a szavakat a és an. Az alábbi példa ezt a reguláris kifejezést szemlélteti:

string pattern = @"\ban?\b";
string input = "An amiable animal with a large snout and an animated nose.";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
   Console.WriteLine($"'{match.Value}' found at position {match.Index}.");

// The example displays the following output:
//        'An' found at position 0.
//        'a' found at position 23.
//        'an' found at position 42.
Dim pattern As String = "\ban?\b"
Dim input As String = "An amiable animal with a large snout and an animated nose."
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'       'An' found at position 0.
'       'a' found at position 23.
'       'an' found at position 42.

A reguláris kifejezésminta a következő táblázatban látható módon van definiálva:

Minta Leírás
\b Kezdje egy szóhatáron.
an? Egy a karakterrel, amelyet nulla vagy egy n karakter követ, egyező karaktert ad meg.
\b Egy szóhatáron végződik.

Pontosan {n} alkalommal egyezzen meg: {n}

Az {n} kvantáló pontosan n-szer egyezik meg az előző elemmel, ahol n minden egész szám. { n} egy mohó kvantor, amelynek lusta megfelelője {n}?.

A reguláris kifejezés \b\d+\,\d{3}\b például egy szóhatárnak próbál megfelelni, amelyet egy vagy több tizedesjegy követ, majd három tizedesjegy, majd egy szóhatár. Az alábbi példa ezt a reguláris kifejezést szemlélteti:

string pattern = @"\b\d+\,\d{3}\b";
string input = "Sales totaled 103,524 million in January, " +
                      "106,971 million in February, but only " +
                      "943 million in March.";
foreach (Match match in Regex.Matches(input, pattern))
   Console.WriteLine($"'{match.Value}' found at position {match.Index}.");

//  The example displays the following output:
//        '103,524' found at position 14.
//        '106,971' found at position 45.
Dim pattern As String = "\b\d+\,\d{3}\b"
Dim input As String = "Sales totaled 103,524 million in January, " + _
                      "106,971 million in February, but only " + _
                      "943 million in March."
For Each match As Match In Regex.Matches(input, pattern)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'       '103,524' found at position 14.
'       '106,971' found at position 45.

A reguláris kifejezésminta a következő táblázatban látható módon van definiálva:

Minta Leírás
\b Kezdje egy szóhatáron.
\d+ Egy vagy több tizedesjegynek felel meg.
\, Megfelel egy vessző karakternek.
\d{3} Három tizedesjegynek felel meg.
\b Egy szóhatáron végződik.

Legalább n-szer egyezés: {n,}

Az {n,} kvantáló legalább n-szer megegyezik az előző elemet, ahol n minden egész szám. { n,} egy mohó kvantor, amelynek lusta megfelelője {n,}?.

A reguláris kifejezés \b\d{2,}\b\D+ például megpróbál illeszkedni egy szóhatárra, amelyet legalább két számjegy követ, majd egy újabb szóhatárra és egy nem számjegy karakterre. Az alábbi példa ezt a reguláris kifejezést szemlélteti. A reguláris kifejezés nem egyezik meg a kifejezéssel "7 days" , mert csak egy tizedesjegyet tartalmaz, de sikeresen megegyezik a kifejezésekkel "10 weeks" és "300 years"a .

string pattern = @"\b\d{2,}\b\D+";
string input = "7 days, 10 weeks, 300 years";
foreach (Match match in Regex.Matches(input, pattern))
   Console.WriteLine($"'{match.Value}' found at position {match.Index}.");

//  The example displays the following output:
//        '10 weeks, ' found at position 8.
//        '300 years' found at position 18.
Dim pattern As String = "\b\d{2,}\b\D+"
Dim input As String = "7 days, 10 weeks, 300 years"
For Each match As Match In Regex.Matches(input, pattern)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'       '10 weeks, ' found at position 8.
'       '300 years' found at position 18.

A reguláris kifejezésminta a következő táblázatban látható módon van definiálva:

Minta Leírás
\b Kezdje egy szóhatáron.
\d{2,} Legalább két tizedesjegynek felel meg.
\b Egy szóhatárnak felel meg.
\D+ Legalább egy nem tizedes számjegynek felel meg.

Egyezés n és m között: {n,m}

Az {n,m} kvantáló legalább n-szer egyezik meg az előző elemmel, de legfeljebb m alkalommal, ahol az n és az m egész szám. { n,m} egy kapzsi kvantor, amelynek lusta egyenértékűje {n,m}?.

Az alábbi példában a reguláris kifejezés (00\s){2,4} két és négy előfordulás között próbál illeszkedni, ahol két nulla számjegyet egy szóköz követ. A bemeneti sztring utolsó része a legfeljebb négy helyett ötször tartalmazza ezt a mintát. Ennek a részsztringnek azonban csak a kezdeti része (a szóközig és az ötödik páros nulláig) felel meg a reguláris kifejezésmintának.

string pattern = @"(00\s){2,4}";
string input = "0x00 FF 00 00 18 17 FF 00 00 00 21 00 00 00 00 00";
foreach (Match match in Regex.Matches(input, pattern))
   Console.WriteLine($"'{match.Value}' found at position {match.Index}.");

//  The example displays the following output:
//        '00 00 ' found at position 8.
//        '00 00 00 ' found at position 23.
//        '00 00 00 00 ' found at position 35.
Dim pattern As String = "(00\s){2,4}"
Dim input As String = "0x00 FF 00 00 18 17 FF 00 00 00 21 00 00 00 00 00"
For Each match As Match In Regex.Matches(input, pattern)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'       '00 00 ' found at position 8.
'       '00 00 00 ' found at position 23.
'       '00 00 00 00 ' found at position 35.

Nulla vagy több időpont egyeztetése (lusta egyezés): *?

A *? kvantáló a nulla vagy több alkalommal, de a lehető legkevesebb alkalommal felel meg az előző elemnek. Ez a lusta megfelelője a mohó kvantálónak *.

Az alábbi példában a reguláris kifejezés \b\w*?oo\w*?\b megegyezik a sztringet ootartalmazó összes szóval.

 string pattern = @"\b\w*?oo\w*?\b";
 string input = "woof root root rob oof woo woe";
 foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
    Console.WriteLine($"'{match.Value}' found at position {match.Index}.");

 //  The example displays the following output:
//        'woof' found at position 0.
//        'root' found at position 5.
//        'root' found at position 10.
//        'oof' found at position 19.
//        'woo' found at position 23.
Dim pattern As String = "\b\w*?oo\w*?\b"
Dim input As String = "woof root root rob oof woo woe"
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'       'woof' found at position 0.
'       'root' found at position 5.
'       'root' found at position 10.
'       'oof' found at position 19.
'       'woo' found at position 23.

A reguláris kifejezésminta a következő táblázatban látható módon van definiálva:

Minta Leírás
\b Kezdje egy szóhatáron.
\w*? Nulla vagy több szó karaktert tartalmaz, de a lehető legkevesebb karaktert.
oo Megegyezik a sztringgel oo.
\w*? Nulla vagy több szó karaktert tartalmaz, de a lehető legkevesebb karaktert.
\b Egy szóhatáron végződik.

Egyeztesse egyszer vagy többször (lassú egyezés): +?

A +? kvantáló egy vagy több alkalommal, de a lehető legkevesebb alkalommal felel meg az előző elemnek. Ez a lusta megfelelője a mohó kvantálónak +.

A reguláris kifejezés \b\w+?\b például egy vagy több, szóhatárok szerint elválasztott karakternek felel meg. Az alábbi példa ezt a reguláris kifejezést szemlélteti:

string pattern = @"\b\w+?\b";
string input = "Aa Bb Cc Dd Ee Ff";
foreach (Match match in Regex.Matches(input, pattern))
   Console.WriteLine($"'{match.Value}' found at position {match.Index}.");

//  The example displays the following output:
//        'Aa' found at position 0.
//        'Bb' found at position 3.
//        'Cc' found at position 6.
//        'Dd' found at position 9.
//        'Ee' found at position 12.
//        'Ff' found at position 15.
Dim pattern As String = "\b\w+?\b"
Dim input As String = "Aa Bb Cc Dd Ee Ff"
For Each match As Match In Regex.Matches(input, pattern)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'       'Aa' found at position 0.
'       'Bb' found at position 3.
'       'Cc' found at position 6.
'       'Dd' found at position 9.
'       'Ee' found at position 12.
'       'Ff' found at position 15.

Egyezés nulla vagy egyszer (lustán egyezés): ??

A ?? kvantáló megfelel az előző nulla vagy egy elemnek, de a lehető legkevesebb alkalommal. Ez a lusta megfelelője a mohó kvantálónak ?.

A reguláris kifejezés ^\s*(System.)??Console.Write(Line)??\(?? például megpróbálja egyezni a karakterláncokkal Console.Write vagy Console.WriteLine. A karakterlánc tartalmazhatja a System.-t Console előtt, és követheti egy nyitó zárójel. A karakterláncnak egy sor elején kell lennie, bár ezt megelőzheti szóköz. Az alábbi példa ezt a reguláris kifejezést szemlélteti:

string pattern = @"^\s*(System.)??Console.Write(Line)??\(??";
string input = "System.Console.WriteLine(\"Hello!\")\n" +
                      "Console.Write(\"Hello!\")\n" +
                      "Console.WriteLine(\"Hello!\")\n" +
                      "Console.ReadLine()\n" +
                      "   Console.WriteLine";
foreach (Match match in Regex.Matches(input, pattern,
                                      RegexOptions.IgnorePatternWhitespace |
                                      RegexOptions.IgnoreCase |
                                      RegexOptions.Multiline))
   Console.WriteLine($"'{match.Value}' found at position {match.Index}.");

//  The example displays the following output:
//        'System.Console.Write' found at position 0.
//        'Console.Write' found at position 36.
//        'Console.Write' found at position 61.
//        '   Console.Write' found at position 110.
Dim pattern As String = "^\s*(System.)??Console.Write(Line)??\(??"
Dim input As String = "System.Console.WriteLine(""Hello!"")" + vbCrLf + _
                      "Console.Write(""Hello!"")" + vbCrLf + _
                      "Console.WriteLine(""Hello!"")" + vbCrLf + _
                      "Console.ReadLine()" + vbCrLf + _
                      "   Console.WriteLine"
For Each match As Match In Regex.Matches(input, pattern, _
                                         RegexOptions.IgnorePatternWhitespace Or RegexOptions.IgnoreCase Or RegexOptions.MultiLine)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'       'System.Console.Write' found at position 0.
'       'Console.Write' found at position 36.
'       'Console.Write' found at position 61.
'       '   Console.Write' found at position 110.

A reguláris kifejezésminta a következő táblázatban látható módon van definiálva:

Minta Leírás
^ Megegyezik a bemeneti adatfolyam kezdetével.
\s* Nulla vagy több szóköz karakterrel egyezik.
(System.)?? Megfelel a sztring System. nullának vagy egy előfordulásának.
Console.Write Megegyezik a sztringgel Console.Write.
(Line)?? Megfelel a sztring Line nullának vagy egy előfordulásának.
\(?? Egyezik a nyitó zárójel nullával vagy egy előfordulásával.

Pontosan n-szer egyezik (lassú illesztés): {n}?

A {n}? kvantifikáló pontosan n alkalommal megegyezik az előző elemmel, ahol n egész szám. Ez a mohó kvantírozó {n} lusta megfelelője.

Az alábbi példában a normál kifejezés \b(\w{3,}?\.){2}?\w{3,}?\b egy webhelycím azonosítására szolgál. A kifejezés egyezik www.microsoft.com és msdn.microsoft.com, de nem egyezik mywebsite vagy mycompany.com.

string pattern = @"\b(\w{3,}?\.){2}?\w{3,}?\b";
string input = "www.microsoft.com msdn.microsoft.com mywebsite mycompany.com";
foreach (Match match in Regex.Matches(input, pattern))
   Console.WriteLine($"'{match.Value}' found at position {match.Index}.");

//  The example displays the following output:
//        'www.microsoft.com' found at position 0.
//        'msdn.microsoft.com' found at position 18.
Dim pattern As String = "\b(\w{3,}?\.){2}?\w{3,}?\b"
Dim input As String = "www.microsoft.com msdn.microsoft.com mywebsite mycompany.com"
For Each match As Match In Regex.Matches(input, pattern)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'       'www.microsoft.com' found at position 0.
'       'msdn.microsoft.com' found at position 18.

A reguláris kifejezésminta a következő táblázatban látható módon van definiálva:

Minta Leírás
\b Kezdje egy szóhatáron.
(\w{3,}?\.) Legalább három szó szerinti karakterrel, de a lehető legkevesebb karakterrel, majd egy pont. Ez a minta az első rögzítési csoport.
(\w{3,}?\.){2}? Az első csoport mintájával kétszer, de amennyire csak lehet kevesebb alkalommal egyezik meg.
\b Egy szóhatáron fejezd be a mérkőzést.

Legalább n időpont egyeztetése (Lazy Match): {n,}?

Az {n,}? kvantáló legalább n az előző elemnek felel meg, ahol n bármilyen egész szám, de a lehető legkevesebb alkalommal. Ez a mohó kvantírozó {n,} lusta megfelelője.

Tekintse meg az {n}? kvantor példáját az előző szakaszban ábraként. A példában szereplő reguláris kifejezés az {n,} kvantor használatával egy legalább három karakterből álló sztringet keres, amelyet egy pont követ.

Egyezés n és m időpont között (lusta egyezés): {n,m}?

Az {n,m}? kvantor az előző elemet n és m alkalom között illeszti, ahol n és m egész számok, de a lehető legkevesebb alkalommal. Ez a mohó kvantor {n,m} lusta megfelelője.

Az alábbi példában a reguláris kifejezés \b[A-Z](\w*?\s*?){1,10}[.!?] egyezik az 1 és 10 szó közötti mondatokkal. A bemeneti sztringben szereplő összes mondatnak megfelel, kivéve egy 18 szót tartalmazó mondatot.

string pattern = @"\b[A-Z](\w*?\s*?){1,10}[.!?]";
string input = "Hi. I am writing a short note. Its purpose is " +
                      "to test a regular expression that attempts to find " +
                      "sentences with ten or fewer words. Most sentences " +
                      "in this note are short.";
foreach (Match match in Regex.Matches(input, pattern))
   Console.WriteLine($"'{match.Value}' found at position {match.Index}.");

//  The example displays the following output:
//        'Hi.' found at position 0.
//        'I am writing a short note.' found at position 4.
//        'Most sentences in this note are short.' found at position 132.
Dim pattern As String = "\b[A-Z](\w*\s?){1,10}?[.!?]"
Dim input As String = "Hi. I am writing a short note. Its purpose is " + _
                      "to test a regular expression that attempts to find " + _
                      "sentences with ten or fewer words. Most sentences " + _
                      "in this note are short."
For Each match As Match In Regex.Matches(input, pattern)
    Console.WriteLine("'{0}' found at position {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'       'Hi.' found at position 0.
'       'I am writing a short note.' found at position 4.
'       'Most sentences in this note are short.' found at position 132.

A reguláris kifejezésminta a következő táblázatban látható módon van definiálva:

Minta Leírás
\b Kezdje egy szóhatáron.
[A-Z] Egyezik egy nagybetűvel az A-Z nagybetűk közül.
(\w*?\s*?) Nulla vagy több szó karaktert, majd egy vagy több szóköz karaktert tartalmaz, de a lehető legkevesebb alkalommal. Ez a minta az első rögzítési csoport.
{1,10} Megegyezik az előző mintával 1 és 10 között.
[.!?] Megfelel bármelyik írásjelnek: ., ! vagy ?.

Mohó és lusta kvantitátorok

Egyes kvantátorok két verzióval rendelkeznek:

  • Egy mohó verzió.

    Egy mohó mennyiségjelző egy elemet próbál a lehető legtöbbször illeszteni.

  • Nem mohó (vagy lusta) változat.

    A nem mohó kvantor a lehető legkevesebb alkalommal próbál egy elemet illeszteni. A kapzsi kvantálót lusta-kvantálóvá alakíthatja egy ? hozzáadásával.

Vegyünk egy reguláris kifejezést, amelynek célja az utolsó négy számjegy kinyerése egy számsorozatból, például hitelkártyaszámból. A kapzsi kvantálót használó * reguláris kifejezés verziója az \b.*([0-9]{4})\b. Ha azonban egy sztring két számot tartalmaz, ez a reguláris kifejezés csak a második szám utolsó négy számjegyével egyezik meg, ahogyan az alábbi példa mutatja:

string greedyPattern = @"\b.*([0-9]{4})\b";
string input1 = "1112223333 3992991999";
foreach (Match match in Regex.Matches(input1, greedyPattern))
   Console.WriteLine($"Account ending in ******{match.Groups[1].Value}.");

// The example displays the following output:
//       Account ending in ******1999.
Dim greedyPattern As String = "\b.*([0-9]{4})\b"
Dim input1 As String = "1112223333 3992991999"
For Each match As Match In Regex.Matches(input1, greedypattern)
    Console.WriteLine("Account ending in ******{0}.", match.Groups(1).Value)
Next
' The example displays the following output:
'       Account ending in ******1999.

A reguláris kifejezés nem egyezik az első számmal, mert a * kvantor a lehető legtöbbször próbálja egyeztetni az előző elemet a teljes sztringben, ezért az egyezést a sztring végén találja meg.

Ez a viselkedés nem a kívánt viselkedés. Ehelyett a *? lusta kvantitálóval mindkét számból kinyerheti a számjegyeket, ahogy az alábbi példa is mutatja:

string lazyPattern = @"\b.*?([0-9]{4})\b";
string input2 = "1112223333 3992991999";
foreach (Match match in Regex.Matches(input2, lazyPattern))
   Console.WriteLine($"Account ending in ******{match.Groups[1].Value}.");

// The example displays the following output:
//       Account ending in ******3333.
//       Account ending in ******1999.
Dim lazyPattern As String = "\b.*?([0-9]{4})\b"
Dim input2 As String = "1112223333 3992991999"
For Each match As Match In Regex.Matches(input2, lazypattern)
    Console.WriteLine("Account ending in ******{0}.", match.Groups(1).Value)
Next
' The example displays the following output:
'       Account ending in ******3333.
'       Account ending in ******1999.

A legtöbb esetben a kapzsi és lusta kvantitátorok reguláris kifejezései ugyanazokat a találatokat adják vissza. A leggyakrabban különböző eredményeket adnak vissza, ha a helyettesítő karakter (.) metakarakterrel használják őket, amely bármilyen karakternek megfelel.

Kvantitátorok és üres egyezések

A kvantorok *, + és {n,m} és a lusta változataik soha nem ismétlődnek meg üres találat után, amikor a rögzítések minimális számát elérik. Ez a szabály megakadályozza, hogy a kvantátorok végtelen hurkokat adjanak meg üres alexpressziós egyezéseken, ha a lehetséges csoportrögzítések maximális száma végtelen vagy közel végtelen.

Az alábbi kód például a metódus meghívásának Regex.Match eredményét jeleníti meg a reguláris kifejezésmintával (a?)*, amely nullával vagy egy a karakter nullával vagy több alkalommal egyezik. Az egyetlen rögzítési csoport rögzíti az összes a és String.Empty elemet, de nincs második üres egyezés, mert az első üres egyezés miatt a kvantor leállítja az ismétlést.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = "(a?)*";
      string input = "aaabbb";
      Match match = Regex.Match(input, pattern);
      Console.WriteLine($"Match: '{match.Value}' at index {match.Index}");
      if (match.Groups.Count > 1) {
         GroupCollection groups = match.Groups;
         for (int grpCtr = 1; grpCtr <= groups.Count - 1; grpCtr++) {
            Console.WriteLine($"   Group {grpCtr}: '{groups[grpCtr].Value}' at index {groups[grpCtr].Index}");
            int captureCtr = 0;
            foreach (Capture capture in groups[grpCtr].Captures) {
               captureCtr++;
               Console.WriteLine($"      Capture {captureCtr}: '{capture.Value}' at index {capture.Index}");
            }
         }
      }
   }
}
// The example displays the following output:
//       Match: 'aaa' at index 0
//          Group 1: '' at index 3
//             Capture 1: 'a' at index 0
//             Capture 2: 'a' at index 1
//             Capture 3: 'a' at index 2
//             Capture 4: '' at index 3
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern As String = "(a?)*"
        Dim input As String = "aaabbb"
        Dim match As Match = Regex.Match(input, pattern)
        Console.WriteLine("Match: '{0}' at index {1}",
                          match.Value, match.Index)
        If match.Groups.Count > 1 Then
            Dim groups As GroupCollection = match.Groups
            For grpCtr As Integer = 1 To groups.Count - 1
                Console.WriteLine("   Group {0}: '{1}' at index {2}",
                                  grpCtr,
                                  groups(grpCtr).Value,
                                  groups(grpCtr).Index)
                Dim captureCtr As Integer = 0
                For Each capture As Capture In groups(grpCtr).Captures
                    captureCtr += 1
                    Console.WriteLine("      Capture {0}: '{1}' at index {2}",
                                      captureCtr, capture.Value, capture.Index)
                Next
            Next
        End If
    End Sub
End Module
' The example displays the following output:
'       Match: 'aaa' at index 0
'          Group 1: '' at index 3
'             Capture 1: 'a' at index 0
'             Capture 2: 'a' at index 1
'             Capture 3: 'a' at index 2
'             Capture 4: '' at index 3

A minimális és maximális számú rögzítést meghatározó rögzítési csoport és a rögzített számú rögzítést meghatározó rögzítési csoport közötti gyakorlati különbség megtekintéséhez vegye figyelembe a reguláris kifejezésmintákat (a\1|(?(1)\1)){0,2} és (a\1|(?(1)\1)){2}a . Mindkét reguláris kifejezés egyetlen rögzítési csoportból áll, amely a következő táblázatban van definiálva:

Minta Leírás
(a\1 Bármelyik egyezés a az első rögzített csoport értékével együtt ...
|(?(1) … vagy ellenőrzi, hogy az első rögzített csoport definiálva van-e. A (?(1) szerkezet nem definiál rögzítési csoportot.
\1)) Ha az első rögzített csoport létezik, illeszkedjen az értékéhez. Ha a csoport nem létezik, akkor a csoport egyezni fog String.Empty.

Az első reguláris kifejezés megpróbálja a mintát nullától két alkalommal egyezésbe hozni; a második reguláris kifejezés pontosan kétszer próbál egyezést létrehozni. Mivel az első minta a String.Empty első rögzítésével eléri a rögzítések minimális számát, soha nem ismétlődik, hogy megpróbáljon illeszkedni a\1-hez. A {0,2} kvantáló csak üres egyezéseket engedélyez az utolsó iterációban. Ezzel szemben a második reguláris kifejezés illeszkedik a-re, mert újraértékeli a\1 még egyszer. Az iterációk minimális száma (2) arra kényszeríti a motort, hogy üres egyezés után ismételjen.

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern, input;

      pattern = @"(a\1|(?(1)\1)){0,2}";
      input = "aaabbb";

      Console.WriteLine($"Regex pattern: {pattern}");
      Match match = Regex.Match(input, pattern);
      Console.WriteLine($"Match: '{match.Value}' at position {match.Index}.");
      if (match.Groups.Count > 1) {
         for (int groupCtr = 1; groupCtr <= match.Groups.Count - 1; groupCtr++)
         {
            Group group = match.Groups[groupCtr];
            Console.WriteLine($"   Group: {groupCtr}: '{group.Value}' at position {group.Index}.");
            int captureCtr = 0;
            foreach (Capture capture in group.Captures) {
               captureCtr++;
               Console.WriteLine($"      Capture: {captureCtr}: '{capture.Value}' at position {capture.Index}.");
            }
         }
      }
      Console.WriteLine();

      pattern = @"(a\1|(?(1)\1)){2}";
      Console.WriteLine($"Regex pattern: {pattern}");
      match = Regex.Match(input, pattern);
         Console.WriteLine($"Matched '{match.Value}' at position {match.Index}.");
      if (match.Groups.Count > 1) {
         for (int groupCtr = 1; groupCtr <= match.Groups.Count - 1; groupCtr++)
         {
            Group group = match.Groups[groupCtr];
            Console.WriteLine($"   Group: {groupCtr}: '{group.Value}' at position {group.Index}.");
            int captureCtr = 0;
            foreach (Capture capture in group.Captures) {
               captureCtr++;
               Console.WriteLine($"      Capture: {captureCtr}: '{capture.Value}' at position {capture.Index}.");
            }
         }
      }
   }
}
// The example displays the following output:
//       Regex pattern: (a\1|(?(1)\1)){0,2}
//       Match: '' at position 0.
//          Group: 1: '' at position 0.
//             Capture: 1: '' at position 0.
//
//       Regex pattern: (a\1|(?(1)\1)){2}
//       Matched 'a' at position 0.
//          Group: 1: 'a' at position 0.
//             Capture: 1: '' at position 0.
//             Capture: 2: 'a' at position 0.
Imports System.Text.RegularExpressions

Module Example
    Public Sub Main()
        Dim pattern, input As String

        pattern = "(a\1|(?(1)\1)){0,2}"
        input = "aaabbb"

        Console.WriteLine("Regex pattern: {0}", pattern)
        Dim match As Match = Regex.Match(input, pattern)
        Console.WriteLine("Match: '{0}' at position {1}.",
                          match.Value, match.Index)
        If match.Groups.Count > 1 Then
            For groupCtr As Integer = 1 To match.Groups.Count - 1
                Dim group As Group = match.Groups(groupCtr)
                Console.WriteLine("   Group: {0}: '{1}' at position {2}.",
                                  groupCtr, group.Value, group.Index)
                Dim captureCtr As Integer = 0
                For Each capture As Capture In group.Captures
                    captureCtr += 1
                    Console.WriteLine("      Capture: {0}: '{1}' at position {2}.",
                                      captureCtr, capture.Value, capture.Index)
                Next
            Next
        End If
        Console.WriteLine()

        pattern = "(a\1|(?(1)\1)){2}"
        Console.WriteLine("Regex pattern: {0}", pattern)
        match = Regex.Match(input, pattern)
        Console.WriteLine("Matched '{0}' at position {1}.",
                          match.Value, match.Index)
        If match.Groups.Count > 1 Then
            For groupCtr As Integer = 1 To match.Groups.Count - 1
                Dim group As Group = match.Groups(groupCtr)
                Console.WriteLine("   Group: {0}: '{1}' at position {2}.",
                                  groupCtr, group.Value, group.Index)
                Dim captureCtr As Integer = 0
                For Each capture As Capture In group.Captures
                    captureCtr += 1
                    Console.WriteLine("      Capture: {0}: '{1}' at position {2}.",
                                      captureCtr, capture.Value, capture.Index)
                Next
            Next
        End If
    End Sub
End Module
' The example displays the following output:
'       Regex pattern: (a\1|(?(1)\1)){0,2}
'       Match: '' at position 0.
'          Group: 1: '' at position 0.
'             Capture: 1: '' at position 0.
'       
'       Regex pattern: (a\1|(?(1)\1)){2}
'       Matched 'a' at position 0.
'          Group: 1: 'a' at position 0.
'             Capture: 1: '' at position 0.
'             Capture: 2: 'a' at position 0.

Lásd még