什么是“嵌套量词”,为什么它会导致我的正则表达式失败?

Posted

技术标签:

【中文标题】什么是“嵌套量词”,为什么它会导致我的正则表达式失败?【英文标题】:What is a "Nested Quantifier" and why is it causing my regex to fail? 【发布时间】:2010-09-17 15:14:18 【问题描述】:

我有这个正则表达式,我在 regex buddy 中构建和测试。

"_ [ 0-9]10+ 1+[ 0-9]10+ 2+[ 0-9]6+ 2[ 0-9]2"

当我在 .Net C# 中使用它时

我收到异常

"parsing \"_ [ 0-9]10+ +[ 0-9]10+  +[ 0-9]6+  [ 0-9]2\" - Nested quantifier +."

这个错误是什么意思?显然 .net 不喜欢这种表达方式。

这里是正则表达式好友,所以你可以理解我的正则表达式意图......

_ [ 0-9]10+ 1+[ 0-9]10+ 2+[ 0-9]6+ 2[ 0-9]2

Match the characters "_ " literally «_ »
Match a single character present in the list below «[ 0-9]10+»
   Exactly 10 times «10+»
   The character " " « »
   A character in the range between "0" and "9" «0-9»
Match the character " " literally « 1+»
   Exactly 1 times «1+»
Match a single character present in the list below «[ 0-9]10+»
   Exactly 10 times «10+»
   The character " " « »
   A character in the range between "0" and "9" «0-9»
Match the character " " literally « 2+»
   Exactly 2 times «2+»
Match a single character present in the list below «[ 0-9]6+»
   Exactly 6 times «6+»
   The character " " « »
   A character in the range between "0" and "9" «0-9»
Match the character " " literally « 2»
   Exactly 2 times «2»
Match a single character present in the list below «[ 0-9]2»
   Exactly 2 times «2»
   The character " " « »
   A character in the range between "0" and "9" «0-9»

总之……

什么是嵌套量词?

【问题讨论】:

【参考方案1】:

.NET 在n 样式量词之后抱怨+,因为它没有任何意义。 n 表示与给定组的 n 完全匹配。 + 表示匹配一个或多个给定组。删除+'s 就可以正常编译了。

"_ [ 0-9]10 1[ 0-9]10 2[ 0-9]6 2[ 0-9]2"

【讨论】:

在某些正则表达式风格中 min,max+ 是所有格量词,但 .Net 不支持它们。如果您正在使用 Regex buddy,您可以通过右键单击合成窗格并从下拉列表中选择“风味”来告诉它您正在使用哪种风味的正则表达式。【参考方案2】:

.NET 不支持possessive quantifier

10+

但是,10 应该具有完全相同的效果。如果最长的匹配失败,+ 会避免回溯并尝试更短的匹配,但由于 10 只能匹配正好 10 个字符开始,这并没有多大效果。

"_ [ 0-9]10 [ 0-9]10 2[ 0-9]6 2[ 0-9]2"

应该没问题。我还删除了“1+”位。由于它只匹配一次,“A1+”相当于“A”。

编辑 正如 Porges 所说,如果您确实需要 .NET 中的所有格量词,那么原子组提供相同的功能,(?>[0-9]*) 等同于 [0-9]*+

【讨论】:

酷。没有意识到一些正则表达式引擎提供了这个选项。 我认为你应该能够通过使用原子组来模拟所有格量词,即使用[0-9]10+,而不是(?>[0-9]10)【参考方案3】:

他们是对的。这个版本的正则表达式不会失败:

(_ [ 0-9]10)+(\s1)+([ 0-9]10)+(\s2)+([ 0-9]6)+\s2[ 0-9]2

注意使用括号来创建可以重复一次或多次的组。此外,您应该更具体并使用 \s 而不是空格,因为模式空格可能有意义,也可能没有意义。

顺便说一句,这个正则表达式看起来并不那么有用。您可能想问另一个问题,类似于“如何使用正则表达式匹配此模式?”

【讨论】:

嗯,这只是一个 sn-p,完整的正则表达式是这样... _ [0-9]10 1[ 0-9]10 2[ 0- 9]6 2[ 0-9]2|_ [ 0-9]10 1[0-9]10 2[ 0-9]6 2 [ 0-9]2|_ [ 0-9]10 1[ 0-9]10 2[ 0-9]6 2[0-9] 2它的返回字段只要一个不是空白的......我喜欢 \s 的想法。谢谢 我几乎可以肯定正则表达式可能会被缩减。说真的,问一个关于如何做的问题并提供一些示例数据。【参考方案4】:

如果您在 RegexBuddy 顶部的工具栏中选择 .NET 风格,RegexBuddy 将指示 .NET 不支持所有格量​​词,例如 10+。

由于 10 只允许特定数量的重复,因此使其惰性或所有格毫无意义,即使它在支持惰性和/或所有格量词的正则表达式风格中在语法上是有效的。从您的正则表达式中删除 + 符号将使其在 .NET 中正常工作。

在其他情况下,在 RegexBuddy 的 Create 选项卡中双击所有格量词的错误。 RegexBuddy 然后将所有格量词替换为功能等效的原子组。

如果您在 RegexBuddy 的“使用”选项卡上为 .NET 语言生成源代码 sn-p,RegexBuddy 将自动替换源代码 sn-p 中正则表达式中的所有格量词。

【讨论】:

以上是关于什么是“嵌套量词”,为什么它会导致我的正则表达式失败?的主要内容,如果未能解决你的问题,请参考以下文章

包括所有特殊字符的正则表达式模式

什么是 '?-mix' 在 Ruby 正则表达式中

正则表达式 - grep、sed、awk - 处理大型文本文件

正则和re模块

正则表达式(re模块)

vim怎么正则查询一个词出现的次数