我正在使用正则表达式条件(.net regex)。
假设这是我的字符串eat, drink, run
我想知道这个正则表达式
(eat)
在第1组中存储“eat”,用括号括起来,这个
(?: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
答案 0 :(得分:1)
您似乎误解了conditionals in regex的概念。
特殊构造
(?ifthen|else)
允许您创建条件正则表达式。如果 if 部分的计算结果为true,那么正则表达式引擎将尝试匹配then部分。否则,将尝试使用 else 部分。 ... 您可以在 if 部分查看到目前为止捕获组是否参与了比赛。将捕获组的编号放在括号内,并将其用作if部分。
来自MSDN Details of Regular Expression Behavior:
条件评估:
(?(expression)yes|no)
和(?(name)yes|no)
,其中expression
是要匹配的子表达式,name
是捕获组的名称,yes
是匹配的字符串如果匹配expression
或name
是有效的非空捕获组,则no
是要匹配的子表达式{{1} }未匹配或expression
不是有效的非空捕获组。
记住这些信息,很容易解释你的模式行为。
为什么这个条件正则表达式不起作用?
name
将无效,因为正则表达式引擎找到(eat)(?(1)a)
,将其放入捕获组(进入堆栈#1)并遇到条件语句。它检查第1组是否参加了比赛(由于eat
)。是的,它确实。然后,引擎会在(?(1)...)
之后的条件(if
)中查找a
部分。没有eat
,因此整场比赛失败。
为什么这个有条件的正则表达式有用呢?
在a
中,您将一个捕获组放在字符串锚点的开头,该字符串锚点与由于(^)?eat(?(1)a)
而未参与匹配的空字符串匹配,因此,?
语句为寻找(?(1)...)
部分 - 缺少(=空字符串会做)。换句话说,条件语句的计算结果为 false ,并且从未执行else
之后的a
搜索。因此,有一个匹配。作为experiment,您可以从正则表达式中移除eat
:没有匹配项,因为没有?
,第一个捕获的组参加比赛,条件评估为 true 。
如果您需要将第一个捕获组评估强制为true并仍然将其作为可选项,则需要使用原子组(like this)?
来强制使用.NET正则表达式引擎将第一个捕获组视为有效的非空捕获组。
答案 1 :(得分:0)
对于Dot-Net样式,请使用(?>(^)?)eat(?(1)a)
或
对于Perl样式,请使用(?>(^)?)eat(?(1)a)
或(^)?+eat(?(1)a)
这会强制引擎匹配BOS(如果是这种情况)
即使它是可选的。
如果没有占有地使用,引擎将选择不来匹配(^)?
如果必须在尝试满足条件(?(1)a)
时,如果不是
可能的任何其他方式。