在正则表达式中,(?!^)\G和\G(?!^)的区别是什么?

4

给定这两个正则表达式:

(?!^)\G

并且

\G(?!^)

"

\G锚点之前和之后使用负向先行断言有什么区别?

"

2
我不理解这个问题。\G和负向先行断言是完全正交的。无论另一个是否存在,每个都会执行其预定功能。 - Jon
2
我想知道为什么你会发布这样的非实际问题?我是否可以期待第三个问题,例如\K(?=.*\d)foo(?=.*\d)\Kfoo之间的区别? - HamZa
2
对于那些感兴趣的人,这里有一个pcretest dump,请注意它可能与.net不同。我怀疑机会非常小... - HamZa
2个回答

2

它们完全相同,因为我们将检查完全正交的逻辑条件。 实际上,在两个示例中都使用了负向预查。

(?!^)

与锚点相结合
\G

因此,我们要求的是同时满足以下条件的内容:
  • 在前一个匹配的结尾或者字符串的开头进行匹配

  • 不跟随任何在字符串开头的内容。


2
“^” 不检查字符,它检查字符串的开头。当然,“(?!^)” 可能匹配失败。它的意思是(相当于)“我们不在字符串的开头”。 - Timwi
不,它的意思是“跟在我们后面的内容不能出现在字符串的开头”。 - Roberto Reale
1
那在逻辑上和我说的是一样的 :) - Timwi
我猜测你是出于恶意而给我的回答点了踩。请不要这样做。只有当回答错误时才应该点踩。 - Timwi
@Robin,我所提到的正则表达式是(?!^)\G\G(?!^)(根据原始问题)。虽然你对(?!^)\Gabc\Gabc的理解肯定是正确的,但它们是全新的正则表达式。 - Roberto Reale
显示剩余19条评论

1
逻辑上,它们是相同的。它们在功能上等效。 (?!^)\G 在字符串中的相同位置检查两个不同的条件,因此检查顺序没有逻辑差异。
这些条件如下:
- (?!^) = “我们不在输入字符串的开头”。 - \G = “我们在前一个匹配结束的位置”。
然而,就性能而言,我怀疑(尽管我没有测试)后者更快。我预计正则表达式引擎会优化以使以 \G 开头的正则表达式仅从前一个匹配的结尾处开始执行,而另一个则会在整个字符串中“寻找”前一个匹配的位置。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接