正则表达式组如何在条件内表现?

How regex groups behaves inside conditional?

我很难使用正则表达式条件 (.net regex)。

假设这是我的字符串 eat, drink, run

我想知道这个正则表达式是否正确

(eat)

在第1组中存储"eat",用括号括起来,而this

(?:eat)

不将匹配存储在任何组中,因为括号内有一个“?:”

那么,为什么这个条件正则表达式不起作用?

(eat)(?(1)a)

显示一条消息说组 1 中没有存储任何内容,不是(吃)正确存储为一组吗?

为什么这个条件正则表达式有效?

(^)?eat(?(1)a)

返回 "eat" 存储在组 1 中,不是应该存储在组中的匹配项必须用括号括起来吗?

请尝试在许多站点中找到解释,我正在这个 .NET 正则表达式页面中测试这些正则表达式 http://derekslager.com/blog/posts/2007/09/a-better-dotnet-regular-expression-tester.ashx

你好像误解了conditionals in regex的概念。

A special construct (?ifthen|else) allows you to create conditional regular expressions. If the if part evaluates to true, then the regex engine will attempt to match the then part. Otherwise, the else part is attempted instead. ... you can check in the if part whether a capturing group has taken part in the match thus far. Place the number of the capturing group inside parentheses, and use that as the if part.

来自 MSDN Details of Regular Expression Behavior

Conditional evaluation: (?(expression)yes|no) and (?(name)yes|no), where expression is a subexpression to match, name is the name of a capturing group, yes is the string to match if expression is matched or name is a valid, non-empty captured group, and no is the subexpression to match if expression is not matched or name is not a valid, non-empty captured group.

记住这些信息,就很容易解释您的模式行为。

why this conditional regex doesn't work?

(eat)(?(1)a) 将不起作用,因为正则表达式引擎找到 eat,将其放入捕获组(放入堆栈 #1)并遇到条件语句。它检查第 1 组是否参加了比赛(由于 (?(1)...))。是的,它确实。然后引擎会在 eat 之后查找条件 (a) 中的 if 部分。没有a,因此,整个匹配失败

And why this conditional regex does work?

(^)?eat(?(1)a) 中,您将捕获组放在字符串锚点的开头,该字符串锚点匹配由于 ? 而未参与匹配的空字符串,因此,(?(1)...)语句正在寻找 else 部分 - 缺少该部分(= 空字符串即可)。换句话说,条件语句的计算结果为 false,并且永远不会在 eat 之后立即搜索 a。因此,有一场比赛。作为 experiment,您可以从正则表达式中删除 ?:将不会匹配,因为 没有 ?,第一个捕获的组 确实参与了比赛并且条件评估为

如果您需要将第一个捕获组评估强制为 true 并且仍然将其作为可选的,您将需要使用原子组 (like this) (?>(^)?) 来强制执行 .NET 正则表达式引擎将第一个捕获组视为 有效的非空捕获组

对于 Dot-Net 风格,使用 (?>(^)?)eat(?(1)a)
对于 Perl 风格,使用 (?>(^)?)eat(?(1)a)(^)?+eat(?(1)a)

这会强制引擎匹配 BOS(如果是这样的话)
即使它是可选的。

如果不使用所有格,引擎会选择来匹配(^)?
如果必须满足条件 (?(1)a) if not
可能的任何其他方式。