Kvantifikátory v regulárních výrazech

Kvantifikátory určují, kolik instancí znaku, skupiny nebo třídy znaků musí být ve vstupu k nalezení shody. Následující tabulka uvádí kvantifikátory podporované rozhraním .NET.

Kvantifikátor greedy Opožděný kvantifikátor Description
* *? Porovná nulu nebo vícekrát.
+ +? Porovná se jednou nebo vícekrát.
? ?? Porovná se nulou nebo jednou.
{N} {N}? Přesně nkrát odpovídá.
{N,} {N,}? Shodovat alespoň nkrát .
{N,M} {N,M}? Porovná se od n do m krát.

Množství n a m jsou celočíselné konstanty. Obvykle jsou kvantifikátory greedy; způsobí, že modul regulárních výrazů bude odpovídat co nejvíce výskytům konkrétních vzorů. Připojení znaku ? k kvantifikátoru je opožděné; 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 opožděnými kvantifikátory najdete v části Greedy a Lazy Kvantifikátory dále v tomto tématu.

Důležité

Vnoření kvantifikátorů (například vzor regulárního výrazu (a*)* ) může zvýšit počet porovnání, které musí modul regulárních výrazů provést, jako exponenciální funkce počtu znaků ve vstupním řetězci. Další informace o tomto chování a jeho alternativním řešení najdete v tématu Backtracking.

Kvantifikátory regulárních výrazů

Následující části obsahují seznam kvantifikátorů podporovaných regulárními výrazy .NET.

Poznámka

Pokud jsou v vzoru regulárního výrazu zjištěny znaky *, +, ?, {a }, 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 tyto znaky interpretovat jako literální znaky mimo třídu znaků, musíte je řídicím znakem před nimi použít zpětné lomítko. Řetězec v vzoru regulárního výrazu se například \* interpretuje jako literální znak hvězdičky (*).

Shoda s nulou nebo více časy: *

Kvantifikátor * odpovídá předchozímu prvku nula nebo vícekrát. Je ekvivalentní kvantifikátoru {0,} . * je greedy kvantifikátor, jehož opožděný ekvivalent je *?.

Následující příklad ukazuje tento regulární výraz. Z devíticiferných skupin ve vstupním řetězci se pět shoduje se vzorem a čtyřmi (95, 929, 9219a 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("'{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.

Vzor regulárního výrazu je definován tak, jak je znázorněno v následující tabulce.

Vzor Description
\b Začne na hranici slova.
91* Porovná hodnotu "9" následovanou nulou nebo více znaky "1".
9* Porovná nula nebo více znaků "9".
\b Skončí na hranici slova.

Shoda jednou nebo vícekrát: +

Kvantifikátor + odpovídá předchozímu prvku jednou nebo vícekrát. Je ekvivalentní {1,}. + je greedy kvantifikátor, jehož opožděný ekvivalent je +?.

Například regulární výraz \ban+\w*?\b se pokusí spárovat celá slova, která začínají písmenem a následovaným jednou nebo více instancemi písmena n. Následující příklad ukazuje tento regulární výraz. Regulární výraz odpovídá slovům an, , announcementannuala 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("'{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.      

Vzor regulárního výrazu je definován tak, jak je znázorněno v následující tabulce.

Vzor Description
\b Začne na hranici slova.
an+ Porovná znak "a" následovaný jedním nebo více znaky "n".
\w*? Porovná znak slova nula nebo vícekrát, ale co nejvícekrát.
\b Skončí na hranici slova.

Shoda s nulou nebo jednou: ?

Kvantifikátor ? odpovídá předchozímu prvku nula nebo jednou. Je ekvivalentní {0,1}. ? je greedy kvantifikátor, jehož opožděný ekvivalent je ??.

Například regulární výraz \ban?\b se pokusí spárovat 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 ukazuje tento regulární výraz.

string pattern = @"\ban?\b";
string input = "An amiable animal with a large snount 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 snount 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 tak, jak je znázorněno v následující tabulce.

Vzor Description
\b Začne na hranici slova.
an? Porovná znak "a" následovaný nulou nebo jedním znakem "n".
\b Skončí na hranici slova.

Přesně n Časy: {n}

N}{ kvantifikátor odpovídá předchozímu prvku přesně n krát, kde n je libovolné celé číslo. {n} je kvantifikátor greedy, jehož opožděný ekvivalent je {n}?.

Regulární výraz \b\d+\,\d{3}\b se například pokusí shodovat s hranicí 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 ukazuje 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("'{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.

Vzor regulárního výrazu je definován tak, jak je znázorněno v následující tabulce.

Vzor Description
\b Začne na hranici slova.
\d+ Porovná jednu nebo více desítkových číslic.
\, Porovná znak čárky.
\d{3} Porovná tři desítkové číslice.
\b Skončí na hranici slova.

Porovná alespoň nkrát: {n,}

N,}{ kvantifikátor odpovídá předchozímu prvku alespoň nkrát, kde n je libovolné celé číslo. {n,} je kvantifikátor greedy, jehož opoždě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 následovanými ohraničením slova a neciferným znakem. Následující příklad ukazuje 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 and 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("'{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.

Vzor regulárního výrazu je definován tak, jak je znázorněno v následující tabulce.

Vzor Description
\b Začne na hranici slova.
\d{2,} Porovná alespoň dvě desetinná čísla.
\b Porovná hranici slova.
\D+ Porovná alespoň jednu ne desetinnou číslici.

Shoda mezi n a m časy: {n,m}

Kvantifikátor {nm,} 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 greedy kvantifikátor, jehož opožděný ekvivalent je {nm,}?.

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. Všimněte si, že 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ětce (až do mezery a páté dvojice nul) ale 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("'{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.

Porovná nulu nebo vícekrát (opožděná shoda): *?

Kvantifikátor *? odpovídá předchozímu prvku nula nebo vícekrát, ale co nejvícekrát. Je to opoždě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("'{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.

Vzor regulárního výrazu je definován tak, jak je znázorněno v následující tabulce.

Vzor Description
\b Začne na hranici slova.
\w*? Porovná nula nebo více znaků slova, ale co nejvíce znaků.
oo Porovná řetězec "oo".
\w*? Porovná nula nebo více znaků slova, ale co nejvíce znaků.
\b Konec na hranici slova.

Shodovat se jednou nebo vícekrát (opožděná shoda): +?

Kvantifikátor +? odpovídá předchozímu prvku jednou nebo vícekrát, ale co nejvícekrát. Je to opožděný protějšek kvantifikátoru +greedy .

Regulární výraz \b\w+?\b například odpovídá jednomu nebo více znakům odděleným hranicemi slov. 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("'{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.

Shoda s nulou nebo jednou (opožděná shoda): ??

Kvantifikátor ?? odpovídá předchozímu prvku nula nebo jednorázově, ale co nejvícekrát. Je to opožděný protějšek kvantifikátoru ?greedy .

Regulární výraz ^\s*(System.)??Console.Write(Line)??\(?? se například pokusí shodovat s řetězci Console.Write nebo Console.WriteLine. Řetězec může také obsahovat "System" před "Konzola" a může následovat levá závorka. Řetězec musí být na začátku řádku, i když může předcházet prázdným znakem. 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("'{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.

Vzor regulárního výrazu je definován tak, jak je znázorněno v následující tabulce.

Vzor Description
^ Porovná začátek vstupního streamu.
\s* Porovná žádný nebo více prázdných znaků.
(System.)?? Porovná nulu nebo jeden výskyt řetězce "System".
Console.Write Porovná řetězec Console.Write.
(Line)?? Porovná nula nebo jeden výskyt řetězce "Řádek".
\(?? Porovná nulu nebo jeden výskyt počáteční závorky.

Přesně n časy (opožděná shoda): {n}?

N}?{ kvantifikátor přesně odpovídá předchozímu prvkun, kde n je celé číslo. Je to opožděný protějšek kvantifikátoru { greedy n}.

V následujícím příkladu se regulární výraz \b(\w{3,}?\.){2}?\w{3,}?\b používá k identifikaci adresy webu. Všimněte si, že odpovídá "www.microsoft.com" a "msdn.microsoft.com", ale neodpovídá "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("'{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.

Vzor regulárního výrazu je definován tak, jak je znázorněno v následující tabulce.

Vzor Description
\b Začne na hranici slova.
(\w{3,}?\.) Porovná alespoň 3 znaky slova, ale co nejvíce znaků následovaných tečkou nebo tečkou. Toto je první zachytávající skupina.
(\w{3,}?\.){2}? Porovná vzor v první skupině dvakrát, ale co nejvícekrát.
\b Ukončete shodu na hranici slova.

Shodte alespoň nkrát (opožděná shoda): {n,}?

N,}?{ kvantifikátor odpovídá předchozímu prvku alespoň n časy, kde n je celé číslo, ale co nejvícekrát. Je to opožděný protějšek kvantifikátoru { greedy 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,}, aby odpovídal řetězci, který má alespoň tři znaky následované tečkou.

Shoda mezi n a m Times (Opožděná shoda): {n,m}?

Kvantifikátor {nm,}? odpovídá předchozímu prvku mezi n a m časy, kdy n a m jsou celá čísla, ale co nejvícekrát. Je to opožděný protějšek kvantifikátoru { greedy nm,}.

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í jedno a deset 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("'{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.

Vzor regulárního výrazu je definován tak, jak je znázorněno v následující tabulce.

Vzor Description
\b Začne na hranici slova.
[A-Z] Porovná velká písmena od A do Z.
(\w*?\s*?) Porovná nula nebo více znaků slova následovaných jedním nebo více prázdnými znaky, ale co nejvícekrát. Toto je první skupina zachycení.
{1,10} Porovná předchozí vzor mezi 1 a 10krát.
[.!?] Porovná některý z interpunkčních znaků ".", "!", nebo "?".

Greedy a Lazy Kvantifikátory

Řada kvantifikátorů má dvě verze:

  • Greedy verze.

    Greedy kvantifikátor se snaží co nejvíce spárovat prvek.

  • Nechtěná (nebo opožděná) verze.

    Kvantifikátor, který není greedy, se snaží co nejvíce spárovat prvek. Greedy kvantifikátor můžete změnit na opožděný kvantifikátor jednoduše přidáním ?.

Představte si jednoduchý 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á kvantifikátor greedy, 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 ******{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.

Regulární výraz neodpovídá prvnímu číslu, protože * kvantifikátor se snaží spárovat předchozí prvek co nejvícekrát v celém řetězci, a proto najde shodu na konci řetězce.

Toto není požadované chování. 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 ******{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.

Ve většině případů regulární výrazy s greedy a opožděný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á libovolnému znaku.

Kvantifikátory a prázdné shody

Kvantifikátory *, +a nm,} a { jejich opožděné protějšky se nikdy neopakují po prázdné shodě, když byl nalezen minimální počet zachycení. Toto pravidlo zabraňuje kvantifikátorům v zadávání nekonečných smyček na prázdném dílčím výrazu, pokud je maximální počet možných zachytávání skupin nekonečné nebo téměř nekonečné.

Například následující kód ukazuje výsledek volání Regex.Match metody se vzorem (a?)*regulárního výrazu , který odpovídá nule nebo jednomu znaku "a" nula nebo vícekrát. Všimněte si, že jedna skupina zachytávání zachycuje každou "a" a také String.Empty, ale že neexistuje žádná druhá prázdná shoda, protože první prázdná shoda způsobí, že kvantifikátor přestane opakovat.

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

Pokud chcete vidět praktický rozdíl mezi zachytáváním skupiny, která definuje minimum 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ávání skupiny, která je definovaná jako v následující tabulce.

Vzor Description
(a\1 Buď odpovídají "a" spolu s hodnotou první zachycené skupiny ...
|(?(1) … nebo otestujte, zda byla definována první zachycená skupina. (Všimněte si, že (?(1) konstruktor nedefinuje zachytávání skupiny.)
\1)) Pokud první zachycená skupina existuje, odpovídá její hodnotě. Pokud skupina neexistuje, skupina se bude shodovat String.Empty.

První regulární výraz se pokusí shodovat s tímto vzorem mezi nulou a dvěma časy; druhá, přesně dvakrát. Vzhledem k tomu, že první vzor dosáhne minimálního počtu zachycení s prvním zachycením String.Empty, nikdy se nezopakuje, aby se pokusil shodovat a\1; {0,2} kvantifikátor umožňuje pouze prázdné shody v poslední iteraci. Naproti tomu druhý regulární výraz odpovídá "a", protože se vyhodnotí a\1 podruhé; minimální počet iterací, 2, vynutí, aby se modul opakoval 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: {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.

Viz také