限定符

更新:2010 年 10 月

限定符指定在输入中必须存在字符、组或字符类的多少个实例才能找到匹配项。 下表列出了 .NET Framework 支持的限定符。

贪婪的限定符

惰性限定符

说明

*

*?

匹配零次或多次。

+

+?

匹配一次或多次。

?

??

匹配零次或一次。

{n}

{n}?

精确匹配 n 次。

{n,}

{n,}?

至少匹配 n 次。

{n,m}

{n,m}?

匹配 n 到 m 次。

数量 n 和 m 是整数常数。 通常,限定符是贪婪的;它们使正则表达式引擎将尽可能多地匹配特定模式的匹配项。 在 ? 字符后追加限定符使其成为惰性的;它使正则表达式引擎可以尽可能少的匹配匹配项。 有关贪婪限定符与惰性限定符之间差别的完整描述,请参见本主题后面部分的贪婪限定符与惰性限定符一节。

重要说明重要事项

作为输入字符串中字符数量的幂函数,嵌套限定符(例如,如正则表达式模式 (a*)* 的操作)可以增加正则表达式引擎必须执行的比较的数量。关于此行为和其解决方法的更多信息,请参见 回溯

正则表达式限定符

下面几节列出了 .NET Framework 正则表达式支持的限定符。

注意注意

如果在正则表达式模式中遇到 *、+、?、{ 和 } 字符,将正则表达式引擎将它们解释为限定符或限定符构造的一部分,除非它们包括在字符类中。若要将其解释为字符类之外的文本字符,必须将它们通过在前面加一个反斜杠进行转义。例如,正则表达式模式中的字符串 \* 被解释为原义星号(“*”)字符。

匹配零次或多次:*

* 限定符匹配前面的元素零次或多次。 它等效于 {0,} 限定符。 * 是贪婪限定符,对应的惰性限定符是 *?。

下面的示例演示了此正则表达式。 在输入字符串内的 9 个数字中,有 5 个与模式匹配,有 4 个(95、929、9129 和 9919)不匹配。

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.
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.

正则表达式模式的定义如下表所示。

模式

说明

\b

在单词边界处开始。

91*

匹配后跟零或多个“1”字符的“9”。

9*

匹配零个或多个“9”字符。

\b

在单词边界处结束。

匹配一次或多次:+

+ 限定符匹配前面的元素一次或多次。 它等效于 {1,}。 + 是贪婪限定符,对应的惰性限定符是 +?。

例如,正则表达式 \ban+\w*?\b 尝试匹配以字母 a 开头且后跟字母 n 的一个或多个实例的完整单词。 下面的示例演示了此正则表达式。 该正则表达式匹配单词 an、annual、announcement 和 antique,但不匹配 autumn 和 all。

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.      
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.      

正则表达式模式的定义如下表所示。

模式

说明

\b

在单词边界处开始。

an+

匹配后跟一个或多个“n”字符的“a” 。

\w*?

匹配上字字符零次或多次,但次数尽可能少。

\b

在单词边界处结束。

匹配零次或一次:?

? 限定符匹配前面的元素零次或一次。 它等效于 {0,1}。 ? 是贪婪限定符,对应的惰性限定符是 ??。

例如,正则表达式 \ban?\b 尝试匹配以字母 a 开头且后跟字母 n 的零个或一个实例的完整单词。 换言之,它尝试匹配单词 a 和 an。 下面的示例演示了此正则表达式。

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.
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.

正则表达式模式的定义如下表所示。

模式

说明

\b

在单词边界处开始。

an?

匹配后跟零或一个“n”字符的“a” 。

\b

在单词边界处结束。

精确匹配 n 次:{n}

{n} 限定符准确匹配前面的元素 n 次,其中 n 是任何整数。 {n} 是过激限定符,对应的惰性限定符是 {n}?。

例如,正则表达式 \b\d+\,\d{3}\b 尝试匹配如下字符串:先是一个字边界,然后是一个或多个十进制数字,后面再跟 3 个十进制数字,最后又是一个字边界。 下面的示例演示了此正则表达式。

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.
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.

正则表达式模式的定义如下表所示。

模式

说明

\b

在单词边界处开始。

\d+

匹配一个或多个十进制数字。

\,

匹配逗号字符。

\d{3}

匹配三个十进制数字。

\b

在单词边界处结束。

至少匹配 n 次:{n,}

{n,} 限定符匹配前面的元素至少 n 次,其中 n 是任何整数。 {n,} 是过激限定符,对应的惰性限定符是 {n}?。

例如,正则表达式 \b\d{2,}\b\D+ 尝试匹配如下字符串:先是一个字边界,然后是至少 2 个数字,然后再跟一个字边界和一个非数字字符。 下面的示例演示了此正则表达式。 该正则表达式不能匹配短语 "7 days",原因是该短语只包含一个十进制数字;但该表达式可成功匹配短语 "10 weeks and 300 years"。

 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.
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.

正则表达式模式的定义如下表所示。

模式

说明

\b

在单词边界处开始。

\d{2,}

匹配至少量个十进制数字。

\b

与字边界匹配。

\D+

匹配至少一个非十进制数字。

匹配 n 到 m 次:{n,m}

{n,m} 限定符匹配前面的元素至少 n 次,但不超过 m 次,其中 n 和 m 为整数。 {n,m} 是过激限定符,对应的惰性限定符是 {n,m}?。

在下面的示例中,正则表达式 (00\s){2,4} 尝试匹配两个相连的零和一个紧随的空格,且匹配 2 到 4 个实例。 注意输入字符串的最后包含此模式 5 次,而不是最大的 4 次。 但是,仅此子字符串的开头(一直到空格和第五对 0)与该正则表达式模式匹配。

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.
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.

匹配零次或多次(惰性匹配):*?

*? 限定符可以匹配前导元素一次或多次,但次数尽可能少。 它是与贪婪限定符 * 对应的惰性部分。

在下面的示例中,正则表达式 \b\w*?oo\w*?\b 与包含字符串 oo 的所有词匹配。

 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.
 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.

正则表达式模式的定义如下表所示。

模式

说明

\b

在单词边界处开始。

\w*?

匹配零个或多个字字符,但字符尽可能少。

oo

匹配字符串“oo”。

\w*?

匹配零个或多个字字符,但字符尽可能少。

\b

在单词边界处结束。

匹配一次或多次(惰性匹配):+?

+? 限定符可以匹配前导元素一次或多次,但次数尽可能少。 它是与贪婪限定符 + 对应的惰性部分。

例如,正则表达式 \b\w+?\b 匹配由字边界分隔的一个或多个字符。 下面的示例演示了此正则表达式。

 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.
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.

匹配零次或一次(惰性匹配):??

?? 限定符可以匹配前导元素零次或一次,但次数尽可能少。 它是与贪婪限定符 ? 对应的惰性部分。

例如,正则表达式 ^\s*(System.)??Console.Write(Line)??\(?? 尝试匹配 "Console.Write" 或者 "Console.WriteLine" 字符串。 字符串还可以在“控制台”前包含“系统.”,它后面可以跟着左括号。 该字符串必须位于一行的开头,不过它的前面可以有空白。 下面的示例演示了此正则表达式。

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.
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.

正则表达式模式的定义如下表所示。

模式

说明

^

匹配输入字符串的开始部分。

\s*

匹配零个或多个空白字符。

(System.)??

匹配字符串“System.”的零个或一个匹配项。

Console.Write

匹配字符串"Console.Write"。

(Line)??

匹配字符串"Line"零次或一次。

\(??

匹配左括号的零个或一个匹配项。

精确匹配 n 次(惰性匹配):{n}?

{n}? 限定符准确匹配前面的元素 n 次,其中 n 是任何整数。 它是与贪婪限定符 {n}+ 对应的惰性部分。

在下面的示例中,使用正则表达式 \b(\w{3,}?\.){2}?\w{3,}?\b 标识网站地址。 请注意它与“www.microsoft.com”和“msdn.microsoft.com”相匹配,但与“mywebsite”或“mycompany.com”不匹配。

 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.
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.

正则表达式模式的定义如下表所示。

模式

说明

\b

在单词边界处开始。

(\w{3,}? \.)

至少匹配 3 个字字符,但字符尽可能少,后跟圆点或句点字符。 这是第一个捕获组。

(\w{3,}? \.){2}?

与第一个组中的模式匹配两次,但次数尽可能少。

\b

在单词边界处结束匹配。

至少匹配 n 次(惰性匹配):n,}?

{n,}? 限定符匹配前面的元素至少 n 次,其中 n 是任何整数,但是次数尽可能少。 它是与过激限定符 {n,} 相对应的惰性限定符。

要查看实例,请参阅上一节中 {n}? 限定符的示例。 该例中的正则表达式使用 {n,} 限定符来匹配含有至少 3 个字符且这些字符后面跟有句点的字符串。

匹配 n 到 m 次(惰性匹配):{n,m} ?

{n,m}? 限定符匹配前面的元素 n 到 m 次,其中 n 和 m 为整数,但是次数尽可能少。 它是与贪婪限定符 {n,m} 对应的惰性部分。

在下面的示例中,正则表达式 \b[A-Z](\w*\s+){1,10}?[.!?] 匹配包含一到十个词的句子。 该示例匹配输入字符串中除了包含 18 个单词的那个句子之外的所有句子。

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.
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.

正则表达式模式的定义如下表所示。

模式

说明

\b

在单词边界处开始。

[A-Z]

匹配从 A 到 Z 的大写字符。

(\w*\s+)

匹配零个或多个字字符,后跟一个或多个空白字符。 这是第一个捕获组。

{1,10}?

匹配上一个模式的次数介于 1 和 10 之间,但次数尽可能少。

[.!?]

匹配标点字符“.”、“!”或“?”中的任何一个。

贪婪限定符与惰性限定符

一些限定符有两种版本:

  • 贪婪版本。

    贪婪限定符尝试尽可能多地匹配元素。

  • 非贪婪(惰性)版本。

    非贪婪限定符尝试尽可能少地匹配元素。 只需添加 ?,便可以将贪婪限定符转换为惰性限定符。

考虑一个简单的正则表达式,旨在从信用卡号之类的数字串中提取最后四位数。 使用 * 贪婪限定符的正则表达式版本为 \b.*([0-9]{4})\b。 但是,如果一个字符串包含两组数字,则此正则表达式只与第二组数字的最后四位数匹配,如下面的示例所示。

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.
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 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.
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.

在大多数情况下,带有贪婪限定符和惰性限定符的正则表达式将返回相同的匹配项。 在与通配符 (.) 元字符(该元字符匹配任何字符)一起使用时,它们多数情况下会返回不同的结果。

限定符和空匹配

限定符 *,+ 和 {n,m} 以及他们的贪婪限定符在找到最小捕获数后为空匹配后不再重复。 此规则会阻止限定符在可能的群组捕获的最大数目为无限大或接近无限大时进入空子表达式匹配的无限循环。

例如,下面的代码显示调用正则表达式模式 (a?)* 的 Regex.Match 方法的结果,将匹配零个或一个 "a" 字符零次或多次。 请注意,单个捕获组捕获每个“a”以及 String.Empty,但没有第二个空匹配,因为第一个空匹配导致数量值停止重复。

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
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

要查看定义最小和最大捕获数与定义固定捕获数的捕获组之间的实际差异,请考虑正则表达式模式 (a\1|(?(1)\1)){0,2} 和 (a\1|(?(1)\1)){2}。 这两个正则表达式都包含一个捕获组,如下表中所定义。

模式

说明

(a\1

随着第一次捕获组的值匹配 "a"……

|(?(1)

… 或测试是否已定义第一个捕获组。 (请注意,(?(1) 构造不定义捕获组。)

\1))

如果第一个捕获分组存在,则与其值相匹配。 如果分组不存在,则分组将与 String.Empty 相匹配。

第一个正则表达式试图在零至两倍之间匹配此模式;第二个则完全是两倍。 由于第一个模式在第一次捕获 String.Empty 时达到其最小捕获量,因此它绝不会重复尝试匹配 a\1;{0,2} 限定符只允许在最后的迭代中存在空匹配。 与之相反,第二个常规表达式与“a”匹配,因为它会再一次计算 a\1;最小迭代次数为 2,可强制引擎在空匹配后重复。

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.
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.

请参见

概念

正则表达式语言元素

回溯

修订记录

Date

修订记录

原因

2010 年 10 月

添加了“限定符和空匹配”节。

信息补充。