如何区分a{n}和a{n+1}?

12

我正在尝试理解以下正则表达式量词(这里的a只是一个示例标记):

a{n}?

问号如何影响上面表达式的匹配?它与下面的表达式有何不同?

a{n}

例如,我会预期模式aa{1}?a可以匹配aaaaa。尽管它可以匹配aaa,但aa不能匹配的。而模式a(a{1})?a可以匹配两个字符串,所以这里括号确实起到了作用。


注意:msdn文章《正则表达式中的量词》对于这两者都有以下说明:

{n}量词将前一个元素精确地匹配n次,其中n是任意整数。

对于{n}?,它补充了以下不是很有帮助的内容:

它是贪婪量词 {n}+ 的惰性对应物。


1
这与C#有什么关系? - Austin Henley
9
看起来好像写那篇文章的人没有考虑他们在写什么。怎么可能有一个贪婪版和懒惰版的“精确匹配n次”呢? - McGarnagle
2
@McGarnagle,我明白可选版本背后的思想(匹配恰好n次或者不匹配),可以通过模式 a(a{1})?a 表达。但你说得对,贪婪模式下的精确计数匹配是什么? - Marius Schulz
6
不在正则表达式中。在评论或回答之前,请先阅读问题。 :-) - Ken White
此答案已添加到Stack Overflow正则表达式FAQ中的“量词>更多差异...”部分。 - aliteralmind
显示剩余2条评论
2个回答

13

没有什么。 这篇文章说明:

{n}定量器完全匹配前面的元素n次,其中n是任何整数。 {n}是贪婪量词,其懒惰等价物为{n}?

{n}? 定量器完全匹配前面的元素n 次,其中n 是任意整数。它是贪婪定量器{n}+的惰性对应项。

请注意,文本完全相同,基本上添加不会改变定量器的行为。看起来.NET的正则表达式引擎支持{n}?作为{n}的替代品。


有趣的是,这篇文章似乎包含一个错误:

{n,}定量器至少匹配前面的元素n次,其中n是任何整数。{n, }是贪婪定量器,其惰性等价物是{n,}?

这是错误的。 {n,} 的惰性等价物是{n,}?,而不是{n}?

更新:文章的新版本已经纠正了这个错误。


所以看起来带问号的版本({n}?)只是为了完整性而实现(和记录),因为它的兄弟 {n,}?{n,m}? 也存在? - Marius Schulz
1
@MariusSchulz 是的,我会这么说。该文章甚至提供了一个使用 {n}? 的示例,但如果将其替换为 {n},该代码的行为是相同的。 - p.s.w.g
11
有些人面对问题时,会想:“我知道,我可以使用正则表达式。” 现在他们有了{n}?个问题。 - Marius Schulz
“仅为完整性而实现(并记录)” - 不,情况恰恰相反...规范和实现必须排除{...}吗?在确切计数的情况下,没有理由这样做,而且有很多不这样做的理由。 - Jim Balter
它是贪婪量词{n}+的懒惰对应项 - 这是一个错误(在支持它的实现中,{n}+是占有性的,而不仅仅是贪婪的),但文档已经更改,不再这样说了。 - Jim Balter

1
更多的是一条通知,而不是一个答案,但如果您计划在不同的语言中使用相同的模式,或者决定使用其他正则表达式库与.NET一起使用,则需要了解这一点。关于:

我本来希望模式aa{1}?a可以匹配aaa和aa,但它只匹配了aaa,而没有匹配aa。

在大多数正则表达式引擎中,a{n}和a{n}?会产生相同的结果(它们被视为贪婪版本和非贪婪版本,但是数量限定符是固定的)。 但是,在Oniguruma和Onigmo正则表达式引擎中,情况并非如此。 在这些引擎中,a{n}?的行为类似于(?:a{n})?。由于存在用于这些库的.NET包装器,因此有必要进行澄清。与sed、grep和dbms中使用的ERE(扩展正则表达式)相同。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接