当两边都被某个字符串包围时试图排除匹配
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
,但它应该仍然匹配pen
或nest
中的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))a
或a(?!(?<=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
代表您的消费模式部分可以匹配的字符数。在这里,不清楚该模式实际上可以匹配多少个字符,您可能会使用(?<!¸ª(?!.1,2¸ª))()(ɣʷ|h₂|r₂|r₃|w|j)(?:e|o|ø|ɑ|i|ɚ|y|u|a)
,但我没有任何边缘情况可以测试。
进一步增强这一点可能会产生(?<!¸ª(?!.1,2¸ª))()(ɣʷ|[hr]₂|r₃|w|j)([eoøɑiɚyua])
(demo)。
【讨论】:
以上是关于当两边都被某个字符串包围时试图排除匹配的主要内容,如果未能解决你的问题,请参考以下文章
从 hive 表中查询数据时,哪种状态最好排除 NULL 和空格