我正在尝试弄清楚事情实际上如何与积极前瞻一起工作。在尝试这样做的时候,我已经达到了想要捕捉任何东西的程度 ABC和PQR在ABC和PQR之间的某处包含'mao'。
事情似乎与之合作:
ABC(?=.*?mao).*?PQR
除了一种情况外它匹配正常,请看我的屏幕截图:
我认为红色标记的块不应该匹配。
任何人都可以解释我在这里做错了什么,为什么匹配?
答案 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
编辑:哦,我的,有点早 - 为了满足问题中给出的要求,根本不需要使用前瞻。这就足够了:
ABC.*mao.*PQR
当然,这会出现重新出现的开始(ABC
)和结束(PQR
)令牌的问题,例如ABCandABCmaoPQR
和ABCmaoPQRmaoPQR
,它们可能与您的匹配程度更高我也喜欢。 I've updated the regex here to include these sample cases
编辑2:刚看到您的一个测试字符串ABC1234sakasdf mao mao aslkdfPQR dsfgasd mao maoPQR
已经涵盖了我在上面段落中提到的内容。我需要一杯咖啡。