使用肯定前瞻时不一致

时间:2016-10-06 08:52:01

标签: regex

我正在尝试弄清楚事情实际上如何与积极前瞻一起工作。在尝试这样做的时候,我已经达到了想要捕捉任何东西的程度 ABC和PQR在ABC和PQR之间的某处包含'mao'。

事情似乎与之合作:

ABC(?=.*?mao).*?PQR

除了一种情况外它匹配正常,请看我的屏幕截图:

enter image description here

我认为红色标记的块不应该匹配。

I have tried it here

任何人都可以解释我在这里做错了什么,为什么匹配?

2 个答案:

答案 0 :(得分:2)

(?=.*?mao)可以在 mao之后找到PQR ,因为.匹配任何字符(如果DOTALL模式不是ON,除了linebreak之外的所有字符)符号)。在zxcABCdddddddPQRaasd which contains mao inside中,mao出现在与PQR位于同一行的换行符号之外的任何0 +字符之后,因此前瞻返回 true

为避免这种情况,请使用tempered greedy token

ABC(?=(?:(?!PQR).)*mao).*?PQR
      ^^^^^^^^^^^^^

请参阅this demo(您也可以使用*?代替*,这只会让它变得懒惰。)

(?=(?:(?!PQR).)*mao)构造只会返回 true ,如果{0}字符出现mao字符序列之后出现PQR(即if { {1}}未出现在PQR之前。

答案 1 :(得分:1)

如果你想“捕获ABC和PQR之间的任何东西,其中包括'mao'在ABC和PQR之间的某个地方”,你不需要在预测中包含.*。只需使用:

ABC.*(?=mao).*PQR

Test yourself

编辑:哦,我的,有点早 - 为了满足问题中给出的要求,根本不需要使用前瞻。这就足够了:

ABC.*mao.*PQR

当然,这会出现重新出现的开始(ABC)和结束(PQR)令牌的问题,例如ABCandABCmaoPQRABCmaoPQRmaoPQR,它们可能与您的匹配程度更高我也喜欢。 I've updated the regex here to include these sample cases

编辑2:刚看到您的一个测试字符串ABC1234sakasdf mao mao aslkdfPQR dsfgasd mao maoPQR已经涵盖了我在上面段落中提到的内容。我需要一杯咖啡。