Kvantifierare i reguljära uttryck

Kvantifierare anger hur många instanser av en tecken-, grupp- eller teckenklass som måste finnas i indata för att en matchning ska hittas. I följande tabell visas de kvantifierare som stöds av .NET:

Girig kvantifierare Lat kvantifierare beskrivning
* *? Matchar noll eller fler gånger.
+ +? Matchar en eller flera gånger.
? ?? Matchar noll eller en gång.
{N} {N}? Matchar exakt n gånger.
{N,} {N,}? Matchar minst n gånger.
{n m,} {n m,}? Matchar från n till m gånger.

Antalet n och m är heltalskonstanter. Vanligtvis är kvantifierare giriga. De gör att motorn för reguljära uttryck matchar så många förekomster av vissa mönster som möjligt. Om du lägger till tecknet i ? en kvantifierare blir det lat. Det gör att motorn för reguljära uttryck matchar så få förekomster som möjligt. En fullständig beskrivning av skillnaden mellan giriga och lata kvantifierare finns i avsnittet Giriga och lata kvantifierare senare i den här artikeln.

Viktigt!

Kapslade kvantifierare, till exempel mönster för reguljära uttryck (a*)*, kan öka antalet jämförelser som motorn för reguljära uttryck måste utföra. Antalet jämförelser kan öka som en exponentiell funktion för antalet tecken i indatasträngen. Mer information om det här beteendet och dess lösningar finns i Backtracking.

Kvantifierare för reguljära uttryck

I följande avsnitt visas de kvantifierare som stöds av reguljära .NET-uttryck:

Kommentar

Om tecknen *, +, ?, {och } påträffas i ett reguljärt uttrycksmönster tolkar motorn för reguljära uttryck dem som kvantifierare eller en del av kvantifierarkonstruktionerna om de inte ingår i en teckenklass. Om du vill tolka dessa som literaltecken utanför en teckenklass måste du undvika dem genom att föregå dem med ett omvänt snedstreck. Strängen \* i ett reguljärt uttrycksmönster tolkas till exempel som ett literalt asterisktecken ("*").

Matcha noll eller fler gånger: *

Kvantifieraren * matchar föregående element noll eller fler gånger. Det motsvarar kvantifieraren {0,} . * är en girig kvantifierare vars lata motsvarighet är *?.

I följande exempel visas det här reguljära uttrycket. Fem av de nio siffergrupperna i indatasträngen matchar mönstret och fyra (95, 929, 9219och 9919) gör det inte.

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.

Mönster för reguljära uttryck definieras enligt följande tabell:

Mönster beskrivning
\b Anger att matchningen måste starta vid en ordgräns.
91* Matchar ett 9 följt av noll eller fler 1 tecken.
9* Matchar noll eller fler 9 tecken.
\b Anger att matchningen måste sluta vid en ordgräns.

Matcha en eller flera gånger: +

Kvantifieraren + matchar föregående element en eller flera gånger. Det motsvarar {1,}. + är en girig kvantifierare vars lata motsvarighet är +?.

Det reguljära uttrycket \ban+\w*?\b försöker till exempel matcha hela ord som börjar med bokstaven a följt av en eller flera instanser av bokstaven n. I följande exempel visas det här reguljära uttrycket. Det reguljära uttrycket matchar orden an, annual, announcement, och antique, och matchar autumn korrekt inte och 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.

Mönster för reguljära uttryck definieras enligt följande tabell:

Mönster beskrivning
\b Börja vid en ordgräns.
an+ Matchar ett a följt av ett eller flera n tecken.
\w*? Matchar ett ordtecken noll eller fler gånger men så få gånger som möjligt.
\b Avsluta vid en ordgräns.

Matcha noll eller en gång: ?

Kvantifieraren ? matchar föregående element noll eller en gång. Det motsvarar {0,1}. ? är en girig kvantifierare vars lata motsvarighet är ??.

Det reguljära uttrycket \ban?\b försöker till exempel matcha hela ord som börjar med bokstaven a följt av noll eller en instans av bokstaven n. Med andra ord försöker den matcha orden a och an. I följande exempel visas det här reguljära uttrycket:

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.

Mönster för reguljära uttryck definieras enligt följande tabell:

Mönster beskrivning
\b Börja vid en ordgräns.
an? Matchar ett a följt av noll eller ett n tecken.
\b Avsluta vid en ordgräns.

Matcha exakt n gånger: {n}

N-kvantifieraren matchar föregående element exakt n gånger, där n är något heltal.{} {n är en girig kvantifierare vars lata motsvarighet är{ n}?.}

Det reguljära uttrycket \b\d+\,\d{3}\b försöker till exempel matcha en ordgräns följt av en eller flera decimalsiffror följt av tre decimaltal följt av en ordgräns. I följande exempel visas det här reguljära uttrycket:

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.

Mönster för reguljära uttryck definieras enligt följande tabell:

Mönster beskrivning
\b Börja vid en ordgräns.
\d+ Matchar en eller flera decimaler.
\, Matchar ett kommatecken.
\d{3} Matchar tre decimaler.
\b Avsluta vid en ordgräns.

Matcha minst n gånger: {n,}

N-kvantifieraren matchar föregående element minst n gånger, där n är ett heltal.{,} {n är en girig kvantifierare vars lata motsvarighet är{ n,}?.,}

Till exempel försöker det reguljära uttrycket \b\d{2,}\b\D+ matcha en ordgräns följt av minst två siffror följt av en ordgräns och ett icke-siffrigt tecken. I följande exempel visas det här reguljära uttrycket. Det reguljära uttrycket matchar inte frasen "7 days" eftersom den bara innehåller en decimalsiffra, men den matchar fraserna "10 weeks" och "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.

Mönster för reguljära uttryck definieras enligt följande tabell:

Mönster beskrivning
\b Börja vid en ordgräns.
\d{2,} Matchar minst två decimaler.
\b Matchar en ordgräns.
\D+ Matchar minst en icke-decimalsiffra.

Matcha mellan n och m gånger: {n,m}

N {,m-kvantifieraren} matchar föregående element minst n gånger, men inte fler än m gånger, där n och m är heltal. {n,m} är en girig kvantifierare vars lata motsvarighet är{ n,m.}?

I följande exempel försöker det reguljära uttrycket (00\s){2,4} matcha mellan två och fyra förekomster av två nollsiffror följt av ett blanksteg. Den sista delen av indatasträngen innehåller det här mönstret fem gånger i stället för maximalt fyra. Men endast den första delen av den här delsträngen (upp till blanksteget och det femte paret med nollor) matchar mönstret för reguljära uttryck.

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.

Matcha noll eller fler gånger (lazy match): *?

Kvantifieraren *? matchar föregående element noll eller fler gånger men så få gånger som möjligt. Det är den lata motsvarigheten till den giriga kvantifieraren *.

I följande exempel matchar det reguljära uttrycket \b\w*?oo\w*?\b alla ord som innehåller strängen 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.

Mönster för reguljära uttryck definieras enligt följande tabell:

Mönster beskrivning
\b Börja vid en ordgräns.
\w*? Matchar noll eller fler ordtecken men så få tecken som möjligt.
oo Matchar strängen oo.
\w*? Matchar noll eller fler ordtecken men så få tecken som möjligt.
\b Avsluta på en ordgräns.

Matcha en eller flera gånger (lazy match): +?

Kvantifieraren +? matchar föregående element en eller flera gånger men så få gånger som möjligt. Det är den lata motsvarigheten till den giriga kvantifieraren +.

Det reguljära uttrycket \b\w+?\b matchar till exempel ett eller flera tecken avgränsade med ordgränser. I följande exempel visas det här reguljära uttrycket:

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.

Matcha noll eller en gång (lazy match): ??

Kvantifieraren ?? matchar föregående element noll eller en gång men så få gånger som möjligt. Det är den lata motsvarigheten till den giriga kvantifieraren ?.

Det reguljära uttrycket ^\s*(System.)??Console.Write(Line)??\(?? försöker till exempel matcha strängarna Console.Write eller Console.WriteLine. Strängen kan också innehålla System. före Console, och den kan följas av en inledande parentes. Strängen måste vara i början av en rad, även om den kan föregås av blanksteg. I följande exempel visas det här reguljära uttrycket:

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.

Mönster för reguljära uttryck definieras enligt följande tabell:

Mönster beskrivning
^ Matchar indataströmmens start.
\s* Matchar noll eller fler blankstegstecken.
(System.)?? Matchar noll eller en förekomst av strängen System..
Console.Write Matchar strängen Console.Write.
(Line)?? Matchar noll eller en förekomst av strängen Line.
\(?? Matchar noll eller en förekomst av den inledande parentesen.

Matcha exakt n gånger (lazy match): {n}?

N-kvantifieraren {}?matchar föregående element exakt n gånger, där n är något heltal. Det är den lata motsvarigheten till den giriga kvantifieraren {n}.

I följande exempel används det reguljära uttrycket \b(\w{3,}?\.){2}?\w{3,}?\b för att identifiera en webbplatsadress. Uttrycket matchar www.microsoft.com och men matchar mywebsite inte eller mycompany.commsdn.microsoft.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.

Mönster för reguljära uttryck definieras enligt följande tabell:

Mönster beskrivning
\b Börja vid en ordgräns.
(\w{3,}?\.) Matchar minst tre ordtecken men så få tecken som möjligt, följt av ett punkt- eller punkttecken. Det här mönstret är den första insamlingsgruppen.
(\w{3,}?\.){2}? Matchar mönstret i den första gruppen två gånger men så få gånger som möjligt.
\b Avsluta matchningen på en ordgräns.

Matcha minst n gånger (lazy match): {n,}?

N-kvantifieraren {,}?matchar föregående element minst n gånger, där n är ett heltal men så få gånger som möjligt. Det är den lata motsvarigheten till den giriga kvantifieraren {n,}.

Se exemplet för {n-kvantifieraren}? i föregående avsnitt för en bild. Det reguljära uttrycket i det exemplet använder {n-kvantifieraren,} för att matcha en sträng som har minst tre tecken följt av en punkt.

Matcha mellan n och m times (lazy match): {n,m}?

N {,m-kvantifieraren}? matchar föregående element mellan n och m gånger, där n och m är heltal men så få gånger som möjligt. Det är den lata motsvarigheten till den giriga kvantifieraren {n,m.}

I följande exempel matchar det reguljära uttrycket \b[A-Z](\w*?\s*?){1,10}[.!?] meningar som innehåller mellan 1 och 10 ord. Den matchar alla meningar i indatasträngen förutom en mening som innehåller 18 ord.

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.

Mönster för reguljära uttryck definieras enligt följande tabell:

Mönster beskrivning
\b Börja vid en ordgräns.
[A-Z] Matchar ett versalt tecken från A till Z.
(\w*?\s*?) Matchar noll eller fler ordtecken, följt av ett eller flera blankstegstecken men så få gånger som möjligt. Det här mönstret är den första insamlingsgruppen.
{1,10} Matchar det tidigare mönstret mellan 1 och 10 gånger.
[.!?] Matchar något av skiljetecken ., !eller ?.

Giriga och lata kvantifierare

Vissa kvantifierare har två versioner:

  • En girig version.

    En girig kvantifierare försöker matcha ett element så många gånger som möjligt.

  • En icke-girig (eller lat) version.

    En icke-girig kvantifierare försöker matcha ett element så få gånger som möjligt. Du kan förvandla en girig kvantifierare till en lat kvantifierare genom att lägga till en ?.

Överväg ett reguljärt uttryck som är avsett att extrahera de sista fyra siffrorna från en sträng med siffror, till exempel ett kreditkortsnummer. Versionen av det reguljära uttrycket som använder den * giriga kvantifieraren är \b.*([0-9]{4})\b. Men om en sträng innehåller två tal matchar det här reguljära uttrycket endast de fyra sista siffrorna i det andra talet, vilket visas i följande exempel:

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.

Det reguljära uttrycket matchar inte det första talet eftersom * kvantifieraren försöker matcha det tidigare elementet så många gånger som möjligt i hela strängen, och därför hittar det sin matchning i slutet av strängen.

Det här beteendet är inte det önskade. I stället kan du använda den *? lata kvantifieraren för att extrahera siffror från båda talen, vilket visas i följande exempel:

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.

I de flesta fall returnerar reguljära uttryck med giriga och lata kvantifierare samma matchningar. De returnerar oftast olika resultat när de används med jokertecknet (.) metakarakteraren, som matchar alla tecken.

Kvantifierare och tomma matchningar

Kvantifierarna *, +, och{ n,m} och deras lata motsvarigheter upprepas aldrig efter en tom matchning när det minsta antalet avbildningar har hittats. Den här regeln hindrar kvantifierare från att ange oändliga loopar på tomma underuttrycksmatchningar när det maximala antalet möjliga gruppinsamlingar är oändligt eller nästan oändligt.

Följande kod visar till exempel resultatet av ett anrop till Regex.Match metoden med reguljärt uttrycksmönster (a?)*, som matchar noll eller ett a tecken noll eller fler gånger. Den enskilda insamlingsgruppen samlar in var a och String.Empty, men det finns ingen andra tom matchning eftersom den första tomma matchningen gör att kvantifieraren slutar upprepas.

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

Om du vill se den praktiska skillnaden mellan en insamlingsgrupp som definierar ett minimum och ett maximalt antal avbildningar och en som definierar ett fast antal avbildningar bör du överväga mönster för reguljära (a\1|(?(1)\1)){0,2} uttryck och (a\1|(?(1)\1)){2}. Båda reguljära uttrycken består av en enda insamlingsgrupp, som definieras i följande tabell:

Mönster beskrivning
(a\1 Antingen matchar a tillsammans med värdet för den första insamlade gruppen ...
|(?(1) ... eller testar om den första insamlade gruppen har definierats. Konstruktionen (?(1) definierar inte en insamlingsgrupp.
\1)) Om den första insamlade gruppen finns matchar du dess värde. Om gruppen inte finns matchar String.Emptygruppen .

Det första reguljära uttrycket försöker matcha det här mönstret mellan noll och två gånger. den andra, exakt två gånger. Eftersom det första mönstret når sitt minsta antal avbildningar med sin första avbildning av String.Emptyupprepas det aldrig för att försöka matcha a\1. Kvantifieraren {0,2} tillåter endast tomma matchningar i den senaste iterationen. Det andra reguljära uttrycket matchar a däremot eftersom det utvärderas a\1 en andra gång. Det minsta antalet iterationer, 2, tvingar motorn att upprepas efter en tom matchning.

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.

Se även