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ó | Lazy quantifier | Leírás |
---|---|---|
* |
*? |
Nulla vagy több alkalommal egyezik. |
+ |
+? |
Egy vagy több alkalommal egyezik. |
? |
?? |
Nullával vagy egyszer egyezik. |
{ n } |
{ n }? |
Pontosan n-szer egyezik. |
{ n ,} |
{ n ,}? |
Legalább n-szer egyezik. |
{ 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 kapzsi és a lusta kvantitátorok közötti különbség teljes leírását a cikk későbbi, Mohó és Lazy Quantifiers 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.
Regular Expression Quantifiers
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 szereplő sztring \*
például literális 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 kvantáló, 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("'{0}' found at position {1}.", match.Value, 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 |
Megadja, hogy az egyezésnek egy szóhatáron kell kezdődnie. |
91* |
Egy nullával 9 vagy több 1 karakterrel egyező karaktert ad meg. |
9* |
Nulla vagy több karakternek felel meg 9 . |
\b |
Megadja, 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 kvantáló, amelynek lusta megfelelője .+?
A reguláris kifejezés \ban+\w*?\b
például megpróbál egyezni a betűvel kezdődő teljes szavakkal, majd a betű a
n
egy vagy több példányával. Az alábbi példa ezt a reguláris kifejezést szemlélteti. A reguláris kifejezés megegyezik a szavakkal an
, annual
, announcement
és antique
, és helyesen nem egyezikautumn
.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("'{0}' found at position {1}.", match.Value, 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+ |
a Egy vagy több n karaktert követ. |
\w*? |
Egy szó karakterét nullával vagy többször, de a lehető legkevesebb alkalommal egyezik meg. |
\b |
Egy szóhatáron végződik. |
Nulla vagy egyszeri egyezés: ?
A ?
kvantáló megegyezik az előző nullával vagy egyszer. Ez egyenértékű a {0,1}
. ?
egy kapzsi kvantáló, amelynek lusta megfelelője .??
A reguláris kifejezés \ban?\b
például a betűvel kezdődő teljes szavakat próbálja egyezni, majd a betű a
n
nulla vagy egy példányát. Más szóval, megpróbálja egyezni 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("'{0}' found at position {1}.", match.Value, 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? |
a Egy nullával vagy egy n karaktersel egyező karaktert ad meg. |
\b |
Egy szóhatáron végződik. |
Pontosan n időpont egyeztetése: {n}
Az {
n}
kvantáló pontosan n-szer egyezik meg az előző elemmel, ahol n minden egész szám. {
n egy kapzsi kvantáló, 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("'{0}' found at position {1}.", match.Value, 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. |
\, |
Egyezik egy vesszővel. |
\d{3} |
Három tizedesjegynek felel meg. |
\b |
Egy szóhatáron végződik. |
Legalább n időpont egyeztetése: {n,}
Az {
n,}
kvantáló legalább n-szer megegyezik az előző elemet, ahol n minden egész szám. {
n egy kapzsi kvantáló, amelynek lusta megfelelője n,}?
{
.,}
A reguláris kifejezés \b\d{2,}\b\D+
például egy szóhatárnak próbál megfelelni, amelyet legalább két számjegy követ, amelyet egy szóhatár és egy nem számjegy karakter követ. 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("'{0}' found at position {1}.", match.Value, 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 tizedesjegynek 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 kvantáló, amelynek lusta megfelelő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 megegyezni két nulla számjegy és egy szóköz között. A bemeneti sztring utolsó része a legfeljebb négy helyett ötször tartalmazza ezt a mintát. Ennek a részszűrésnek azonban csak a kezdeti része (a szóközig és az ötödik nulla párig) egyezik meg a reguláris kifejezésmintával.
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("'{0}' found at position {1}.", match.Value, 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 mohó kvantáló *
lusta megfelelője .
Az alábbi példában a reguláris kifejezés \b\w*?oo\w*?\b
megegyezik a sztringet oo
tartalmazó ö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("'{0}' found at position {1}.", match.Value, 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. |
Egy vagy több időpont egyeztetése (lusta egyezés): +?
A +?
kvantáló egy vagy több alkalommal, de a lehető legkevesebb alkalommal felel meg az előző elemnek. Ez a mohó kvantáló +
lusta megfelelője .
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("'{0}' found at position {1}.", match.Value, 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 (lazy egyezés): ??
A ??
kvantáló megfelel az előző nulla vagy egy elemnek, de a lehető legkevesebb alkalommal. Ez a mohó kvantáló ?
lusta megfelelője .
A reguláris kifejezés ^\s*(System.)??Console.Write(Line)??\(??
például megpróbál megegyezni a sztringekkel Console.Write
vagy Console.WriteLine
a . A sztring a korábbiakban Console
is szerepelhetSystem.
, és egy nyitó zárójel is követhető. A sztringnek egy sor elején kell lennie, bár ezt a szóközzel megelőzheti. 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("'{0}' found at position {1}.", match.Value, 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 karaktert egyezik meg. |
(System.)?? |
Egyezik a sztring System. nullával vagy egy előfordulásával. |
Console.Write |
Megegyezik a sztringgel Console.Write . |
(Line)?? |
Egyezik a sztring Line nullával vagy egy előfordulásával. |
\(?? |
Egyezik a nyitó zárójel nullával vagy egy előfordulásával. |
Pontosan n-szer egyezik (lusta egyezés): {n}?
Az {
n}?
kvantáló pontosan n
megfelel az előző elemnek, ahol n az egész szám. Ez a mohó kvantírozó {
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
, de msdn.microsoft.com
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("'{0}' found at position {1}.", match.Value, 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ókarakterek, de a lehető legkevesebb karakter, majd egy pont vagy pont karakter. Ez a minta az első rögzítési csoport. |
(\w{3,}?\.){2}? |
Az első csoportban kétszer, de a lehető legkevesebb alkalommal egyezik meg a mintával. |
\b |
Egy szóhatáron fejezd be az egyezé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ó {
lusta megfelelője.,}
Az ábrát az {
előző szakaszban szereplő n}?
kvantáló példában találja. A példában szereplő reguláris kifejezés az {
n,}
kvantátor használatával egy legalább három karakterből álló sztringet, majd egy pontot használ.
Egyezés n és m időpont között (lusta egyezés): {n,m}?
Az {
n,
m}?
kvantáló megfelel az előző elemnek az idő és m
az idő közöttn
, ahol az n és az m egész szám, de a lehető legkevesebb alkalommal. Ez a mohó kvantáló {
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("'{0}' found at position {1}.", match.Value, 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] |
Egy nagybetűvel egyezik A-tól Z-ig. |
(\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. |
[.!?] |
Egyezik az írásjelek . bármelyikével, ! vagy ? . |
Mohó és lusta kvantitátorok
Egyes kvantátorok két verzióval rendelkeznek:
Egy mohó verzió.
Egy kapzsi kvantáló a lehető legtöbb alkalommal próbál egy elemet egyezni.
Nem mohó (vagy lusta) verzió.
A nem mohó kvantálók a lehető legkevesebb alkalommal próbálnak egy elemet egyezni. A kapzsi kvantálót lusta kvantálóvá alakíthatja egy
?
.
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 ******{0}.", 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 kvantáló a *
lehető legtöbb alkalommal megpróbálja egyezni az előző elemet a teljes sztringben, ezért a sztring végén találja meg az egyezést.
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 ******{0}.", 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 kvantátorok *
, +
és{
az n,
m}
és a lusta társaik soha nem ismétlődnek üres egyezés után, amikor a rögzítések minimális száma megtalálható. 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 egyeseket a
, de String.Emptynincs második üres egyezés, mert az első üres egyezés miatt a kvantátor 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: '{0}' at index {1}",
match.Value, match.Index);
if (match.Groups.Count > 1) {
GroupCollection groups = match.Groups;
for (int grpCtr = 1; grpCtr <= groups.Count - 1; grpCtr++) {
Console.WriteLine(" Group {0}: '{1}' at index {2}",
grpCtr,
groups[grpCtr].Value,
groups[grpCtr].Index);
int captureCtr = 0;
foreach (Capture capture in groups[grpCtr].Captures) {
captureCtr++;
Console.WriteLine(" Capture {0}: '{1}' at index {2}",
captureCtr, capture.Value, 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, egyezzen az értékével. Ha a csoport nem létezik, a csoport egyezni String.Emptyfog. |
Az első reguláris kifejezés nullától kétig próbál megegyezni a mintával; a másodikat, pontosan kétszer. Mivel az első minta eléri a rögzítések minimális számát az első rögzítésével String.Empty, soha nem ismétlődik, hogy megpróbáljon megegyezni a\1
. 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 megegyezik a
, mert másodszor is kiértékeli a\1
. 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: {0}", pattern);
Match match = Regex.Match(input, pattern);
Console.WriteLine("Match: '{0}' at position {1}.",
match.Value, 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: {0}: '{1}' at position {2}.",
groupCtr, group.Value, group.Index);
int captureCtr = 0;
foreach (Capture capture in group.Captures) {
captureCtr++;
Console.WriteLine(" Capture: {0}: '{1}' at position {2}.",
captureCtr, capture.Value, capture.Index);
}
}
}
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) {
for (int groupCtr = 1; groupCtr <= match.Groups.Count - 1; groupCtr++)
{
Group group = match.Groups[groupCtr];
Console.WriteLine(" Group: {0}: '{1}' at position {2}.",
groupCtr, group.Value, group.Index);
int captureCtr = 0;
foreach (Capture capture in group.Captures) {
captureCtr++;
Console.WriteLine(" Capture: {0}: '{1}' at position {2}.",
captureCtr, capture.Value, 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.