模式:a(?(?<! ) )b (c)
输入:a b c
Desription:条件应该与空格匹配,如果lookbehind不是空格。
匹配正确,但捕获组$ 1为空(包含c的instad)。
这是.net正则表达式的问题还是我错过了什么?
示例:http://regexstorm.net/tester?p=a(%3f(%3f%3C!+)+)b+(c)&i=a+b+c
答案 0 :(得分:4)
我不确定是否记录了这种行为(如果是,那么我没有找到它),但使用条件构造,包括显式的零宽度断言作为其表达式{{ 1}}覆盖下一个编号捕获组(清空它)。您可以通过在RegEx下面运行来确认这一点:
(?(?=expression)yes|no)
克服此问题的四种方法:
将表达式括在@DmitryEgorov指出的括号中(同时保留第二个) 捕获组完整)并且不包括在结果中 - 右边 方式:
a(?(?<! ) )b (c)()
由于此行为仅适用于未命名的捕获组 (默认)您可以使用命名捕获组获得预期结果:
a(?((?<! )) )b (c)
在a(?(?<! ) )b (?<first>c)
和条件:
(c)
如果可能,避免使用这样的表达。 E.g:
a(?(?<! ) )(b) (c)
答案 1 :(得分:2)
除了@ revo&#39; s answer:
不仅具有显式零宽度断言的条件构造作为其表达式受到影响。 实际上几乎所有条件表达式都是条件结构 在没有额外括号的情况下使用的带括号的正则表达式(分组,条件,其他特殊)会受到影响。
在这种情况下,有四种类型的(错误)行为:
捕获组数组被破坏(如OP指出),即 紧跟在条件构造之后的捕获组将丢失 其他组向左移动,最后一个捕获组未定义。
在以下示例中,预期的捕获分配是
$1="a", $2="b", $3="c"
而实际结果是
$1="a", $2="c", $3="" (the latter is empty string)
适用于:
(a)(?(?=.) )(b) (c)
- 积极向前看(a)(?(?!z) )(b) (c)
- 负向前瞻(a)(?(?<=.) )(b) (c)
- 积极向后看(a)(?(?<! ) )(b) (c)
- 负面的背后隐藏(a)(?(?: ) )(b) (c)
- 非捕获组(a)(?(?i:.) )(b) (c)
- 群组选项(a)(?(?>.) )(b) (c)
- nonbacktracking subexpression (a)(?(?(1).) )(b) (c)
- 数字((?<n>a))(?(?(n).) )(b)(c)
- 按名称列出的捕获组的嵌套条件(a)(?(?(?:.).) )(b) (c)
- 带有隐式括号的正则表达式的嵌套条件在解析正则表达式时,在运行时抛出ArgumentException
。这实际上是有道理的,因为这明确警告我们一些潜在的正则表达式错误,而不是像前一种情况那样用捕获来玩有趣的技巧。
适用于:
(a)(?(?<n>.) )(b) (c)
,(a)(?(?'n'.) )(b) (c)
- 已命名的群组 - 例外消息:"Alternation conditions do not capture and cannot be named"
(a)(?(?'-n' .) )(b) (c)
,(?<a>a)(?(?<a-n>.) )(b) (c)
- 平衡组 - 异常消息:"Alternation conditions do not capture and cannot be named"
(a)(?(?# comment) )(b) (c)
- 内联评论 - 异常消息:"Alternation conditions cannot be comments"
在模式匹配期间抛出OutOfMemoryException
。
根据我的信念,这显然是一个错误。
适用于:
(a)(?(?i) )(b) (c)
- 内联选项(不要与群组选项混淆)[令人惊讶]按预期工作,但这是一个太人为的例子:
(a)(?(?(.).) )(b) (c)
- 带有明确括号的正则表达式的嵌套条件所有这些正则表达式可以通过将条件表达式括在显式括号中来修复(即,如果表达式本身已经包含括号,则为额外的)。 以下是固定版本(按照外观顺序):
(a)(?((?=.)) )(b) (c)
(a)(?((?!z)) )(b) (c)
(a)(?((?<=.)) )(b) (c)
(a)(?((?<! )) )(b) (c)
(a)(?((?: )) )(b) (c)
(a)(?((?i:.)) )(b) (c)
(a)(?((?>.)) )(b) (c)
(a)(?((?(1).)) )(b) (c)
((?<n>a))(?((?(n).)) )(b)(c)
(a)(?((?(?:.).)) )(b) (c)
(a)(?((?<n>.)) )(b) (c)
(a)(?((?'n'.)) )(b) (c)
(a)(?((?'-n' .)) )(b) (c)
(?<a>a)(?((?<a-n>.)) )(b) (c)
(a)(?((?# comment)) )(b) (c)
(a)(?((?i)) )(b) (c)
(a)(?((?(.).)) )(b) (c)
检查所有这些表达式的示例代码:https://ideone.com/KHbqMI