当两侧被某个字符串包围时尝试排除匹配

Trying to exclude match when surrounded on both sides by a certain string

我想要做的是将正则表达式(JS 风格)修改为 not 匹配,如果模式都在 和 [=37= 之前] 后跟相同的字符串。

打个简单的比方,假设我想匹配 n 的所有实例,这些实例之前和之后都没有 e。因此,例如,正则表达式不应匹配 alkene 中的 n,但 应该 仍匹配 pen 中的 nnest,只有 e 在一侧与 n 直接相邻,而不是在两侧。

我见过的大多数试图找到答案的旧线程基本上都说“只使用负面环视”,但问题是 (?<!e)n(?!e)any[=37= 不匹配] 这些输入 - 因为后视和先行是由正则表达式引擎分别处理的,所以它认为任一条件都足以排除匹配项。

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

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

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

查看你的模式修复(没有任何优化),我在其中进行了前瞻,将其粘贴到 ª 之后的 lookbehind 中,反转了前瞻(即使其为正)并在 [=16= 之前添加了整个模式] 在前瞻中能够到达右侧 ¸ª:

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

或者,如果您将后瞻变成前瞻:

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

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

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

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