当两侧被某个字符串包围时尝试排除匹配
Trying to exclude match when surrounded on both sides by a certain string
我想要做的是将正则表达式(JS 风格)修改为 not 匹配,如果模式都在 和 [=37= 之前] 后跟相同的字符串。
打个简单的比方,假设我想匹配 n
的所有实例,这些实例之前和之后都没有 e
。因此,例如,正则表达式不应匹配 alkene
中的 n
,但 应该 仍匹配 pen
中的 n
或 nest
,只有 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))a
或a(?!(?<=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)。
我想要做的是将正则表达式(JS 风格)修改为 not 匹配,如果模式都在 和 [=37= 之前] 后跟相同的字符串。
打个简单的比方,假设我想匹配 n
的所有实例,这些实例之前和之后都没有 e
。因此,例如,正则表达式不应匹配 alkene
中的 n
,但 应该 仍匹配 pen
中的 n
或 nest
,只有 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))a
或a(?!(?<=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)。