当两边都被某个字符串包围时试图排除匹配

Posted

技术标签:

【中文标题】当两边都被某个字符串包围时试图排除匹配【英文标题】:Trying to exclude match when surrounded on both sides by a certain string 【发布时间】:2021-12-02 11:21:12 【问题描述】:

我要做的是修改正则表达式(JS 风格)以 not 匹配,如果模式之前 后跟相同的字符串。

通过一个简单的类比,假设我想匹配n 的所有实例,这些实例不是在e 之前和之后都存在。因此,例如,正则表达式不应该匹配alkene 中的n,但它应该仍然匹配pennest 中的n,它们只有@987654328 @ 在一侧与n 直接相邻,而不是两者。

我见过的大多数试图找到答案的旧线程基本上都说“只使用否定的环视”,但问题是 (?<!e)n(?!e) 与这些输入中的任何不匹配 - 因为正则表达式引擎分别处理lookbehind 和lookahead,因此它认为任一条件都足以排除匹配项。

(真正的正则表达式是(?<!¸ª)()(ɣʷ|h₂|r₂|r₃|w|j)(?:e|o|ø|ɑ|i|ɚ|y|u|a)(?!¸ª),它与t͡ʃe:h₁dɣʷo¸ªh₂¸ª 中的ɣʷ 不匹配,但这使得问题看起来比实际需要更难解释)

如何修改正则表达式以仅在嵌套模式时排除模式?

【问题讨论】:

【参考方案1】:

此处的(?<!b)a(?!b) 模式必须替换为(?<!b(?=ab))aa(?!(?<=ba)b)。关键是从lookbehind 或lookahead 调用反向lookahead 或lookbehind。

查看您的模式修复(没有任何优化),我在其中进行了前瞻,将其粘贴到 ª 之后的后向内,反转前瞻(即使其成为正数)并在前瞻中将整个模式添加到 ¸ª 之前能够到达右手边¸ª

(?<!¸ª(?!(ɣʷ|h₂|r₂|r₃|w|j)(?:e|o|ø|ɑ|i|ɚ|y|u|a)¸ª))()(ɣʷ|h₂|r₂|r₃|w|j)(?:e|o|ø|ɑ|i|ɚ|y|u|a)

或者,如果您将lookbehind 放入lookahead:

()(ɣʷ|h₂|r₂|r₃|w|j)(?:e|o|ø|ɑ|i|ɚ|y|u|a)(?!(?<=¸ª(ɣʷ|h₂|r₂|r₃|w|j)(?:e|o|ø|ɑ|i|ɚ|y|u|a))¸ª)

参见regex demo(和regex demo #2)。

只要您的模式很简单,最好不要在环顾中重复该模式,您通常可以只使用..x 其中x 代表您的消费模式部分可以匹配的字符数。在这里,不清楚该模式实际上可以匹配多少个字符,您可能会使用(?&lt;!¸ª(?!.1,2¸ª))()(ɣʷ|h₂|r₂|r₃|w|j)(?:e|o|ø|ɑ|i|ɚ|y|u|a),但我没有任何边缘情况可以测试。

进一步增强这一点可能会产生(?&lt;!¸ª(?!.1,2¸ª))()(ɣʷ|[hr]₂|r₃|w|j)([eoøɑiɚyua]) (demo)。

【讨论】:

以上是关于当两边都被某个字符串包围时试图排除匹配的主要内容,如果未能解决你的问题,请参考以下文章

js怎么去掉字符串两边指定字符

php正则获取字符串,给定两边的字符串提取中间字符

从 hive 表中查询数据时,哪种状态最好排除 NULL 和空格

正则表达式查找所有匹配项,除了那些被字符包围的匹配项

JavaScript学习——JavaScript比较和 逻辑运算

pythonchallenge闯关 第3题