Poznámka
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Kvantifikátory určují, kolik instancí znaku, skupiny nebo třídy znaků musí být ve vstupu, aby byla nalezena shoda. Následující tabulka uvádí kvantifikátory podporované rozhraním .NET:
Nenasytný kvantifikátor | Nenáročný kvantifikátor | Popis |
---|---|---|
* |
*? |
Odpovídá nule nebo více výskytům. |
+ |
+? |
Vyskytuje se jednou nebo vícekrát. |
? |
?? |
Odpovídá nule nebo jednou. |
{
n} |
{
n}? |
Odpovídá přesně nkrát . |
{
n,} |
{
n,}? |
Vyskytuje se alespoň n krát. |
{
n, m} |
{
n, m}? |
Odpovídá od n do m krát. |
n
Množství a m
jsou celočíselné konstanty. Kvantifikátory jsou obvykle nenasytné. Způsobí, že modul regulárních výrazů bude odpovídat co nejvíce výskytům konkrétních vzorů. Připojením znaku ?
ke kvantifikátoru je nechamtivý. Způsobí, že modul regulárních výrazů bude odpovídat co nejméně výskytům. Úplný popis rozdílu mezi greedy a línými kvantifikátory najdete v části Greedy a Lazy Kvantifikátory dále v tomto článku.
Důležité
Vnoření kvantifikátorů, jako je vzor regulárního výrazu (a*)*
, může zvýšit počet porovnání, které musí engine regulárních výrazů provést. Počet porovnání se může zvýšit jako exponenciální funkce počtu znaků ve vstupním řetězci. Další informace o tomto chování a jeho alternativních řešeních najdete v tématu Navracení.
Kvantifikátory regulárních výrazů
Následující části uvádějí kvantifikátory podporované regulárními výrazy .NET:
Poznámka:
Pokud jsou znaky *, +, ?, {a } zjištěny ve vzoru regulárního výrazu, modul regulárních výrazů je interpretuje jako kvantifikátory nebo část konstruktorů kvantifikátoru, pokud nejsou zahrnuty do třídy znaků. Chcete-li je interpretovat jako literální znaky mimo třídu znaků, musíte je předcházet zpětným lomítkem. Například řetězec \*
v vzoru regulárního výrazu se interpretuje jako literálový znak hvězdičky (*).
Shoda s nulou nebo více časy: *
Kvantifikátor *
odpovídá předchozímu prvku nulakrát nebo vícekrát. Je to ekvivalent kvantifikátoru {0,}
.
*
je chamtivý kvantifikátor, jehož líný ekvivalent je *?
.
Následující příklad znázorňuje tento regulární výraz. Pět z devíti číslic ve vstupním řetězci odpovídá vzoru a čtyř (95
, 929
, 9219
a 9919
) ne.
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.
Vzor regulárního výrazu je definován, jak je znázorněno v následující tabulce:
Vzor | Popis |
---|---|
\b |
Určuje, že shoda musí začínat na hranici slova. |
91* |
Odpovídá 9 následovanému nulou nebo více znaky 1 . |
9* |
Odpovídá nule nebo více 9 znaků. |
\b |
Určuje, že shoda musí končit na hranici slova. |
Shoda jednou nebo vícekrát: +
Kvantifikátor +
odpovídá předchozímu prvku jednou nebo vícekrát. Je to ekvivalent {1,}
.
+
je nenasytný kvantifikátor, jehož líný ekvivalent je +?
.
Například regulární výraz \ban+\w*?\b
se pokusí shodovat celá slova, která začínají písmenem a
následovaným jednou nebo více instancemi písmena n
. Následující příklad znázorňuje tento regulární výraz. Regulární výraz odpovídá slovům an
, annual
, announcement
, a antique
, a správně se neshoduje autumn
a 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.
Vzor regulárního výrazu je definován, jak je znázorněno v následující tabulce:
Vzor | Popis |
---|---|
\b |
Začni na hranici slova. |
an+ |
a Odpovídá jednomu nebo více n znakům. |
\w*? |
Odpovídá znakovému znaku nula nebo vícekrát, ale pokud možno co nejméněkrát. |
\b |
Skončí na hranici slova. |
Shoda s nulou nebo jedním výskytem: ?
Kvantifikátor ?
odpovídá předchozímu prvku nula nebo jednou. Je to ekvivalent {0,1}
.
?
je nenasytný kvantifikátor, jehož líná verze je ??
.
Regulární výraz \ban?\b
se například pokusí shodovat celá slova, která začínají písmenem a
následovaným nulou nebo jednou instancí písmena n
. Jinými slovy, snaží se spárovat slova a
a an
. Následující příklad znázorňuje tento regulární výraz:
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.
Vzor regulárního výrazu je definován, jak je znázorněno v následující tabulce:
Vzor | Popis |
---|---|
\b |
Začněte na hranici slova. |
an? |
Odpovídá tomuto znaku a , za nímž následuje nula nebo jeden n znak. |
\b |
Skončí na hranici slova. |
Odpovídá přesně n krát: {n}
N {
}
kvantifikátor odpovídá předchozímu prvku přesně nkrát, kde n je jakékoli celé číslo.
{
n je chamtivý kvantifikátor, jehož opožděný ekvivalent je {
n}?
.
Regulární výraz \b\d+\,\d{3}\b
se například pokusí odpovídat hranici slova, následovanou jednou nebo více desetinnými číslicemi, následovanými třemi desetinnými číslicemi, následovanými hranicí slova. Následující příklad znázorňuje tento regulární výraz:
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.
Vzor regulárního výrazu je definován, jak je znázorněno v následující tabulce:
Vzor | Popis |
---|---|
\b |
Začněte na hranici slova. |
\d+ |
Odpovídá jedné nebo více desítkových číslic. |
\, |
Odpovídá znaku čárky. |
\d{3} |
Odpovídá třem desetinným číslicům. |
\b |
Skončí na hranici slova. |
Porovná alespoň n krát: {n,}
N {
,}
kvantifikátor odpovídá předchozímu prvku alespoň nkrát, kde n je jakékoli celé číslo.
{
n je nenasytný kvantifikátor, jehož líný ekvivalent je {
n,}?
.
Regulární výraz \b\d{2,}\b\D+
se například pokusí shodovat s hranicí slova následovanou alespoň dvěma číslicemi, za kterými následuje hranice slova a neciferný znak. Následující příklad znázorňuje tento regulární výraz. Regulární výraz neodpovídá frázi "7 days"
, protože obsahuje pouze jednu desetinnou číslici, ale úspěšně odpovídá frázím "10 weeks"
a "300 years"
.
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.
Vzor regulárního výrazu je definován, jak je znázorněno v následující tabulce:
Vzor | Popis |
---|---|
\b |
Začít na hranici slova. |
\d{2,} |
Odpovídá alespoň dvěma desetinným číslicemi. |
\b |
Odpovídá hranici slova. |
\D+ |
Odpovídá alespoň jedné ne desetinné číslici. |
Shoda mezi n a m časy: {n,m}
Kvantifikátor {
n}
odpovídá předchozímu prvku alespoň nkrát, ale ne více než m krát, kde n a m jsou celá čísla.
{
n,
m}
je nenasytný kvantifikátor, jehož opožděný ekvivalent je {
n,
m}?
.
V následujícím příkladu se regulární výraz (00\s){2,4}
pokusí shodovat mezi dvěma a čtyřmi výskyty dvou nulových číslic následovaných mezerou. Poslední část vstupního řetězce obsahuje tento vzor pětkrát, nikoli maximálně čtyři. Pouze počáteční část tohoto podřetězce (až do mezery a páté dvojice nul) však odpovídá vzoru regulárního výrazu.
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.
Shoda s nulovou nebo více časy (opožděná shoda): *?
Kvantifikátor *?
odpovídá předchozímu prvku nula nebo vícekrát, ale co nejméněkrát. Je to líný protějšek kvantifikátoru *
greedy.
V následujícím příkladu regulární výraz \b\w*?oo\w*?\b
odpovídá všem slovem, která obsahují řetězec oo
.
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.
Vzor regulárního výrazu je definován, jak je znázorněno v následující tabulce:
Vzor | Popis |
---|---|
\b |
Začněte na hranici slova. |
\w*? |
Odpovídá nule nebo více znakům slov, ale co nejméně znaků. |
oo |
Odpovídá řetězci oo . |
\w*? |
Odpovídá nule nebo více znakům slova, ale co nejméně znaků. |
\b |
Končí na hranici slova. |
Shoda jednou nebo vícekrát (líná): +?
Kvantifikátor +?
odpovídá předchozímu prvku jednou nebo vícekrát, ale co nejméněkrát. Je to líný protějšek chamtivého kvantifikátoru +
.
Regulární výraz \b\w+?\b
například odpovídá jednomu nebo více znakům odděleným hranicemi slova. Následující příklad znázorňuje tento regulární výraz:
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.
Shoda s nulou nebo jednou (líná shoda): ??
Kvantifikátor ??
odpovídá předchozímu prvku nula nebo jednou, ale co nejméněkrát. Je to líný protějšek chtivého kvantifikátoru ?
.
Například regulární výraz ^\s*(System.)??Console.Write(Line)??\(??
se pokouší najít shodu s řetězci Console.Write
nebo Console.WriteLine
. Řetězec může obsahovat System.
také před Console
a za ním může následovat levá závorka. Řetězec musí být na začátku řádku, i když může být předcházen mezerami. Následující příklad znázorňuje tento regulární výraz:
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.
Vzor regulárního výrazu je definován, jak je znázorněno v následující tabulce:
Vzor | Popis |
---|---|
^ |
Odpovídá začátku vstupního datového proudu. |
\s* |
Odpovídá nule nebo více prázdných znaků. |
(System.)?? |
Odpovídá nule nebo jednomu výskytu řetězce System. . |
Console.Write |
Odpovídá řetězci Console.Write . |
(Line)?? |
Odpovídá nule nebo jednomu výskytu řetězce Line . |
\(?? |
Odpovídá nule nebo jednomu výskytu levé závorky. |
Přesně n krát (nežravá shoda): {n}?
Kvantifikátor {
n}?
přesně odpovídá předchozímu prvku n
krát, kde n je libovolné celé číslo. Je to líný protějšek kvantifikátoru {
nenasytný n}
.
V následujícím příkladu se regulární výraz \b(\w{3,}?\.){2}?\w{3,}?\b
používá k identifikaci webové adresy. Výraz se shoduje s www.microsoft.com
a msdn.microsoft.com
, ale neshoduje se s mywebsite
nebo 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.
Vzor regulárního výrazu je definován, jak je znázorněno v následující tabulce:
Vzor | Popis |
---|---|
\b |
Začněte na hranici slova. |
(\w{3,}?\.) |
Odpovídá alespoň třem znakům slova, ale co nejméně znaků, za kterými následuje tečka nebo perioda. Tento vzorec je první zachytávací skupina. |
(\w{3,}?\.){2}? |
Odpovídá vzoru v první skupině dvakrát, ale co nejméněkrát. |
\b |
Ukončete shodu na hranici slova. |
Odpovídá alespoň n krát (líná shoda): {n,}?
n-{
kvantifikátor,}?
odpovídá předchozímu prvku alespoň n
krát, kde n je jakékoli celé číslo, ale co nejméněkrát. Je to pomalý protějšek nenasytného kvantifikátoru {
n,}
.
Obrázek najdete v příkladu {
n}?
kvantifikátoru v předchozí části. Regulární výraz v tomto příkladu {
používá kvantifikátor n,}
ke shodě s řetězcem, který má aspoň tři znaky následované tečkou.
Shoda mezi n a m times (opožděná shoda): {n,m}?
Kvantifikátor {
n,
m}?
odpovídá předchozímu prvku mezi n
a m
krát, kde n a m jsou celá čísla co nejméněkrát. Je to líný protějšek chamtivého kvantifikátoru {
n,
m}
.
V následujícím příkladu regulární výraz \b[A-Z](\w*?\s*?){1,10}[.!?]
odpovídá větám, které obsahují 1 až 10 slov. Odpovídá všem větám ve vstupním řetězci s výjimkou jedné věty, která obsahuje 18 slov.
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.
Vzor regulárního výrazu je definován, jak je znázorněno v následující tabulce:
Vzor | Popis |
---|---|
\b |
Začněte na hranici slova. |
[A-Z] |
Odpovídá velkým písmenům od A do Z. |
(\w*?\s*?) |
Odpovídá nule nebo několika znakům slova, za kterými následuje jedno nebo více prázdných znaků, ale co nejvícekrát. Tento vzorec je první zachytávací skupina. |
{1,10} |
Odpovídá předchozímu vzoru mezi 1 a 10krát. |
[.!?] |
Odpovídá libovolnému z interpunkčních znaků . , ! nebo ? . |
Chamtivé a líné kvantifikátory
Některé kvantifikátory mají dvě verze:
Nenasytná verze.
Nenasytný kvantifikátor se snaží co nejvícekrát vyhovovat prvku.
Nenenažraná (nebo líná) verze.
Kvantifikátor, který je nenasytný, se snaží spárovat prvek co nejméněkrát. Kvantifikátor nenasytný můžete změnit na kvantifikátor líný přidáním
?
.
Představte si regulární výraz, který má extrahovat poslední čtyři číslice z řetězce čísel, jako je číslo platební karty. Verze regulárního výrazu, který používá *
nenasytný kvantifikátor, je \b.*([0-9]{4})\b
. Pokud ale řetězec obsahuje dvě čísla, bude tento regulární výraz odpovídat posledním čtyřmístným číslicům druhého čísla, jak ukazuje následující příklad:
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.
Regulární výraz neodpovídá prvnímu číslu, protože *
kvantifikátor se snaží shodovat s předchozím prvkem tolikrát, kolikrát je to možné v celém řetězci, a proto najde shodu na konci řetězce.
Toto chování není požadované. Místo toho můžete pomocí opožděného kvantifikátoru *?
extrahovat číslice z obou čísel, jak ukazuje následující příklad:
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.
Ve většině případů regulární výrazy s nenasytnými a lenivými kvantifikátory vrací stejné shody. Nejčastěji vrací různé výsledky, když se používají se zástupným znakem (.
metacharacter), který odpovídá jakémukoli znaku.
Kvantifikátory a prázdné shody
Kvantifikátory *
, +
a {
n,
m}
a jejich líné protějšky se nikdy neopakují po prázdné shodě, pokud je nalezen minimální počet zachycení. Toto pravidlo zabraňuje kvantifikátorům vstupovat do nekonečných smyček při porovnávání prázdných dílčích výrazů, když je maximální počet možných skupinových zachycení nekonečný nebo téměř nekonečný.
Následující kód například ukazuje výsledek volání Regex.Match metody se vzorem (a?)*
regulárního výrazu , který odpovídá nule nebo jednomu a
znaku nula nebo vícekrát. Jedna zachytávací skupina zachytí každou z těchto a
a String.Empty, ale neexistuje žádná druhá prázdná shoda, protože první prázdná shoda způsobí, že kvantifikátor přestane opakovat se.
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
Chcete-li zjistit praktický rozdíl mezi zachytáváním skupiny, která definuje minimální a maximální počet zachycení a jeden, který definuje pevný počet zachycení, zvažte vzory regulárních výrazů (a\1|(?(1)\1)){0,2}
a (a\1|(?(1)\1)){2}
. Oba regulární výrazy se skládají z jedné zachytávací skupiny, která je definována v následující tabulce:
Vzor | Popis |
---|---|
(a\1 |
Buď se shoduje a s hodnotou první zachycené skupiny ... |
|(?(1) |
… nebo testuje, zda byla definována první zachycená skupina. Konstrukt (?(1) nedefinuje zachycující skupinu. |
\1)) |
Pokud existuje první zachycená skupina, porovnejte její hodnotu. Pokud skupina neexistuje, bude odpovídat String.Empty. |
První regulární výraz se pokusí tento vzor spárovat mezi nulou a dvěma; druhý přesně dvakrát. Vzhledem k tomu, že první šablona dosáhne svého minimálního počtu zachycení při prvním zachycení String.Empty, nikdy se neopakuje ve snaze se pokusit sladit a\1
. Kvantifikátor {0,2}
umožňuje pouze prázdné shody v poslední iteraci. Oproti tomu se druhý regulární výraz shoduje s a
, protože je a\1
vyhodnocen podruhé. Minimální počet iterací 2 donutí proces opakovat se po prázdné shodě.
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.