正则表达式延迟捕获在延迟 "anything" 之后失败......除非我知道接下来会发生什么

regex lazy capturing fails after lazy "anything" ... unless I know what follows

在我的 PCRE 引擎中(以及在 regex101 上)我可以使用这个正则表达式:

abc [\s\S]*?(mno)?

运行 反对这个字符串

abc random mno unknowable

它不会 return mno ... 除非我添加到正则表达式的末尾,像这样:

abc [\s\S]*?(mno)? un

请注意,我已经简化了正则表达式以显示问题...但这来自“现实生活中”的正则表达式,用于解释从业务文档中提取的文本。关键是必须有一些文本(abc)否则正则表达式一定会失败......然后可以有更多的文本和一个可选的 mno ......但不可能猜测“随机”或中间和之后的“不可知”。

经过几天的尝试,我一直没有找到解决方案。希望比我聪明的人知道答案。

您似乎在尝试从模式中捕获可选文本 mno

如果是这样,您可以尝试使用 negative lookahead (?!mno) 来确保 [\s\S] 不会在贪婪时意外地消耗您正在寻找的文本 mno模式。

事实上,当您要捕获的文本是可选的时,您不应该使用非贪婪模式 - 它根本不会匹配任何内容。

这是一个可行的解决方案:

abc (?:(?!mno)[\s\S])*(mno)?

the proof


编辑

如果mno是一个复杂的模式,您仍然可以找到可选的mno。 但是这次,不是mno,你应该排除某些部分abc 作为否定前瞻,所以它不会在搜索复杂模式时跨越另一个abc 部分mno

注意 ? 量词是在包含 mno 的整个事物上,而不是 mno 本身:

abc (?:(?:(?!abc )[\s\S])*(mno))?(?:(?!abc )[\s\S])*

这种情况下还是可以捕捉到复杂的mno.

the proof