正则表达式预测会影响后续匹配吗?

时间:2015-10-26 20:38:00

标签: regex pcre regex-lookarounds lookahead

我正在玩正则表达式,并且遇到了一些我不理解的东西。

我希望这个正则表达式:

(?=1)x

匹配此字符串:

"x1"

但事实并非如此。在ruby中代码如下:

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

这是我期望发生的事情:

  1. 我们从正则表达式解析器的光标“x”开始。
  2. regexp引擎在字符串中搜索“1”并获得匹配。光标仍在“x”
  3. regexp引擎搜索“x”并找到它,因为光标没有移动。
  4. 成功!利润!
  5. 但我显然错了,因为它不匹配。有人可以告诉我哪里出错了吗?

    顺便说一句,我注意到如果前瞻匹配的模式包含我在后续表达式中匹配的字符,它就可以工作。即。 (?=x)x匹配x1就好了。我怀疑这是神秘的关键,但我只是没有得到它。 :)

2 个答案:

答案 0 :(得分:4)

前瞻不会使正则表达式指数向前移动,它会立即显示#34;但它需要在字符串中的当前位置之后存在或不存在某些模式。

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

  1. 下一个字符必须是1
  2. 在此位置右侧,匹配字符x
  3. 这意味着您需要x1,这永远不会是真/永远是假的。这个正则表达式永远不会匹配任何东西。

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

      

    我们将q(?=u)i应用于quit。前瞻现在是积极的,后面是另一个令牌。同样,q匹配qu匹配u。同样,必须放弃前瞻中的匹配,因此引擎会从字符串中的i退回到u。前瞻是成功的,因此引擎继续i。但i无法匹配u。所以这场比赛尝试失败了。所有剩余的尝试都会失败,因为字符串中不再有q个。

    另一个必读资源是Lookarounds Stand their Ground at rexegg.com

      

    前瞻和后瞻并不意味着向前看。他们的意思是 立即查看左侧或右侧的文本 。如果你想进一步检查一根绳子,你需要插入"双筒望远镜"在前瞻中,让你到达你想要检查的字符串的一部分 - 例如.*,或者理想情况下,更具体的标记。

      

    不要指望模式A(?=5)与字符串A中的AB25匹配。许多初学者都认为前瞻说'#34;右边有一个5"但事实并非如此。引擎与A匹配后,前瞻(?=5)断言在字符串中的当前位置,紧随其后的是5。如果您想检查右侧某处(任何地方)是否有5,您可以使用(?=[^5]*5)

答案 1 :(得分:1)

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

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

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

目标文本中的

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

They don't exist AT characters,但他们之间。

这意味着您可以轻松向左或向右看,并应用适当的
断言,即lookAHEAD或lookBEHIND。

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

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

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

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