正则表达式前瞻性是否影响后续匹配



我在玩正则表达式look ahead时遇到了一些我不理解的东西。

我期望这个正则表达式:

(?=1)x

匹配此字符串:

"x1"

但事实并非如此。在ruby中,代码看起来像:

> "x1".match /(?=1)x/
=> nil

以下是我所期望的:

  1. 我们从正则表达式解析器在"x"上的光标开始
  2. 正则表达式引擎在字符串中搜索"1"并获得匹配项。光标仍在"x"上
  3. regexp引擎搜索"x"并找到它,因为光标没有移动
  4. 成功!利润

但我显然错了,因为它不匹配。有人能告诉我哪里出了问题吗?

顺便说一句,我注意到,如果lookahead匹配的模式包含我在后续表达式中匹配的字符,那么它就起作用了。即(?=x)xx1完全匹配。我怀疑这是解开谜团的关键,但我就是不明白。:)

前瞻不会使正则表达式索引向前移动,它"站稳脚跟",但它需要在字符串中的当前位置之后存在或不存在某种模式。

当您使用(?=1)x时,您会告诉正则表达式引擎:

  1. 下一个字符必须是1
  2. 就在这个位置,匹配字符x

这意味着您要求x1,这永远不是真/永远是假。此正则表达式永远不会匹配任何内容。

以下是regular-expressions.com的另一个例子:

让我们将q(?=u)i应用于quit。展望现在是积极的,后面是另一个标志。同样,qq匹配,uu匹配。同样,必须丢弃前瞻中的匹配,因此引擎从字符串中的i后退到u。前瞻性是成功的,因此引擎继续使用i。但i不能与u相匹配。所以这次比赛尝试失败了。所有剩余的尝试也会失败,因为字符串中不再有q

另一个必读资源是rexegg.com:上的Lookarounds Stand their Ground

向前看和向后看并不意味着向前看。它们的意思是立即向左或向右看文本。如果你想进一步检查一段字符串,你需要在展望中插入"双筒望远镜",让你找到你想检查的字符串部分——例如.*,或者理想情况下,更具体的令牌。

不要期望模式A(?=5)与字符串AB25中的A匹配。许多初学者认为前瞻性声明"在右边的某个地方有一个5",但事实并非如此。在引擎匹配A之后,前瞻性声明(?=5)断言在字符串的当前位置,紧接着的是5。如果你想检查右边的某个地方(任何地方)是否有5,你可以使用(?=[^5]*5)

我不会给你一篇关于正则表达式断言的长篇论文。

但我要告诉你,永远不要混淆它们是什么,也永远不要忘记如何使用它们。

正则表达式是从左到右处理(解析)的
它们不过是一个花哨的模板。

ASSERTIONS exist BETWEEN characters在目标文本中,就像它们存在一样
正则表达式中的表达式之间。

They don't exist AT characters,但介于两者之间。

这意味着你可以很容易地向左或向右看,并应用适当的
断言,即lookAHEAD或lookBEHIND。

这就是你真正需要知道的开始。


您的正则表达式(?=1)x,例如:

正则表达式表示在字符之间的位置向前看1
如果它查找并找到1,则继续下一个表达式
下一个表达式是查找文字x

现在,如果下一个字符是1,那么它就不是x
结果是,正则表达式炸弹的,它永远无法匹配任何东西。

最新更新