Share via


限定符

更新: 2008 年 7 月

限定符指定在输入中必须存在前导元素(可以是字符、组或字符类)的多少个实例才能找到匹配项。

.NET Framework 正则表达式中的限定符

下表列出了 .NET Framework 正则表达式支持的限定符。数量 n 和 m 是整数常数。有关贪婪限定符与惰性限定符之间差别的描述,请参见表后面的“贪婪限定符与惰性限定符”一节。

限定符

说明

*

匹配前导元素零次或零次以上。该限定符等效于 {0,}。* 是贪婪限定符,对应的非贪婪限定符是 *?。

例如,正则表达式 \b91*9*\b 尝试匹配字边界后面的数字 9。9 后面可以是数字 1 的零个或零个以上的实例,而数字 1 后面又可跟数字 9 的零个或零个以上的实例。下面的示例演示了此正则表达式。在输入字符串内的 9 个数字中,有 5 个与模式匹配,有 4 个(95、929、9129 和 9919)不匹配。

+

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

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

?

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

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

{n}

匹配前导元素恰好 n 次。{n} 是贪婪限定符,对应的非贪婪限定符为 {n}?。

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

{n,}

匹配前导元素至少 n 次。{n,} 是贪婪限定符,对应的非贪婪限定符为 {n}?。

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

{n,m}

匹配前导元素至少 n 次,但不超过 m 次。{n,m} 是贪婪限定符,对应的非贪婪限定符为 {n,m}?。

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

*?

匹配前导元素零次或零次以上,但次数尽可能少。它是与贪婪限定符 * 相对的惰性限定符。

例如,正则表达式 \b\w*?oo\w*?\b 匹配包含字符串 oo 的所有单词。下面的示例演示了此正则表达式。

+?

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

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

??

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

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

{n}?

匹配前导元素恰好 n 次。它是与贪婪限定符 {n}+ 相对的惰性限定符。

例如,正则表达式 \b(\w{3,}?\.){2}?\w{3,}?\b 匹配恰好两组字符,且每组字符后面跟一个位于字边界的句点。然后,后面再跟另一组字符和一个字边界。此正则表达式标识的应该是一个网站地址。下面的示例演示了该正则表达式。请注意,它匹配 www.microsoft.com 和 mdsn.microsoft.com,但不匹配 mywebsite 或 mycompany.com。

{n,}?

匹配前导元素至少 n 次,但次数尽可能少。它是与贪婪限定符 {n,} 相对的惰性限定符。

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

{n,m}?

匹配前导元素 n 到 m 次,但次数尽可能少。它是与贪婪限定符 {n,m} 相对的惰性限定符。

例如,正则表达式 \b[A-Z](\w*?\s*?){1,10}[.!?] 匹配包含一到十个词的句子。它所匹配的是一个字边界后跟一个大写字母,大写字母后面跟一到十个单词字符组合,每个组合可有零个或零个以上的单词字符和一个空格字符(空格可选)。然后该匹配项由一个句点、一个惊叹号或一个问号结束。下面的示例演示了此正则表达式。该示例匹配输入字符串中除了包含 18 个单词那个句子之外的所有句子。

贪婪限定符与惰性限定符

一些限定符有两种版本:

  • 贪婪版本。

    贪婪限定符尝试尽可能多地匹配它所应用到的元素。

  • 非贪婪(惰性)版本。

    非贪婪限定符尝试尽可能少地匹配它所应用到的元素。

为了演示两者之间的差别,请考虑一个非常简单的正则表达式,它用于从信用卡号之类的数字串中提取最后四位数。使用 * 贪婪限定符的正则表达式版本为 \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.

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

请参见

其他资源

正则表达式语言元素

修订记录

日期

修订记录

原因

2008 年 7 月

大幅修订。

内容 Bug 修复