【发布时间】:2017-08-23 14:43:48
【问题描述】:
(注意:不是Why can't you use repetition quantifiers in zero-width look behind assertions 的重复项;见帖子末尾。)
我正在尝试编写一个匹配 B 的 grep -P (Perl) 正则表达式,但它前面没有 A——不管是否有中间空格。
所以,我尝试了这种消极的后视,并在 regex101.com 中对其进行了测试:
(?<!A)\s*B
这会导致“AB”不匹配,这很好,但“AB”确实会导致匹配,这不是我想要的。
我不确定这是为什么。它与\s*匹配空字符串“”这一事实有关,您可以说在A和B之间存在\s*的无限匹配。但是为什么这会影响“AB”但是不是“AB”?
下面的正则表达式是不是一个合适的解决方案,如果是,为什么它究竟能解决问题?
(?<![A\s])\s*B
我之前发布过此问题,但它被错误地标记为重复问题。我正在寻找的可变长度的东西是匹配的一部分,而不是本身的负面观察的一部分——所以这与另一个问题完全不同。是的,我可以将 \s* 放在否定的后面,但我没有这样做(并且不支持这样做,正如另一个问题所解释的那样)。另外,我对为什么我在上面发布的备用正则表达式有效特别感兴趣,因为我知道它有效,但我不确定为什么。另一个问题没有帮助回答这个问题。
【问题讨论】:
-
你也可以使用
/[^A\s]\s*B/ -
好点。但在我的实际用例中,A 和 B 都是单词,而不仅仅是字符。
-
(?<![A\s])\s*B这不是一个好方法。原因之一是正在进行的巨大回溯。也许有一天你会更关心性能而不是实质。由于您使用的是 Perl,因此请利用它的动词。(?:A\s*B(*SKIP)(*FAIL)|B) -
比较
Regex1: (?<![A\s])\s*B Completed iterations: 50 / 50 ( x 1000 ) Matches found per iteration: 1 Elapsed Time: 0.53 s, 530.18 ms, 530185 µs Regex2: (?:A\s*B(*SKIP)(*FAIL)|B) Completed iterations: 50 / 50 ( x 1000 ) Matches found per iteration: 1 Elapsed Time: 0.18 s, 180.07 ms, 180073 µs -
@sln:特殊动词特别有用,因为它们可以在 A 和 B 是整个单词而不是字符时使用。
标签: regex perl grep negative-lookbehind