【问题标题】:Negative lookahead vs Positive lookahead syntax负前瞻与正前瞻语法
【发布时间】:2016-07-27 09:54:19
【问题描述】:

给定以下文本:

我的名字是 foo。

我叫巴。

目标是返回包含或不包含特定子字符串的每一行,以下正则和负正则表达式模式均可用于返回相同的结果:

正向前瞻:^(?=.*bar).*$ 返回My name is bar.

负前瞻:^((?!foo).)*$ 返回My name is bar.

但是,为什么负前瞻需要嵌套在多组括号中,限定符 . 和量词 * 用括号分隔,而在正前瞻中,它们可以相邻 .*?

【问题讨论】:

    标签: regex lookahead negative-lookahead


    【解决方案1】:

    负前瞻需要嵌套在多组括号中,限定符 . 和量词 * 称为 tempered greedy token。您不必在这种情况下使用它。

    您可以使用锚定在开头的普通前瞻来代替tempered greedy token:

    ^(?!.*foo).*$
    

    见regex demo

    这里,

    • ^ - 匹配字符串开头的位置
    • (?!.*foo) - 如果在线某处有 foo 则匹配失败(如果 DOTALL 模式开启,则为字符串)
    • .*$ - 任何 0+ 个字符(但如果 DOTALL 模式关闭,则为换行符)直到字符串/行的末尾。

    使用什么?

    缓和的贪婪令牌通常效率低得多。当您只需要检查字符串是否包含某些内容时,请使用在开头锚定的前瞻。但是,在某些情况下可能需要经过调和的贪婪令牌。见When to Use this Technique。

    【讨论】:

    • 感谢您提供有关缓和贪婪令牌的其他信息 - 我不知道我在做什么。
    • 实际上,我对著名的Regular expression to match line that doesn't contain a word? 最佳答案停留在这个缓和的贪婪令牌上感到相当失望。这不是此任务的最佳解决方案。瓶颈是在字符串中的每个位置执行的未锚定前瞻,而在我的回答中,前瞻是在开始时触发的,只执行一次。看看一个字符串有没有这个词就足够了。
    • 不错的参考!这就是让我困惑的答案!
    【解决方案2】:

    示例

    给定字符串text = 'a123b456c',我们想使用子字符串'123'作为锚点

    (?=123) Positive lookahead:    Matches substring '123' as a *forward* anchor 
    (?<=123) Positive lookbehind:  Matches substring '123' as a *backward* anchor
    (?!123) Negative lookahead:    Substring not matching '123' as a *forward* anchor
    (?<!123) Negative lookbehind:  Substring not matching '123' as a *backward* anchor
    

    '123' 仅用作锚点,不会被替换。也看看它是如何工作的:

    import re 
    
    text = 'a123b456c'
    
    re.sub('a(?=123)', '@', text) # outputs '@123b456c' note '123' not replaced
    re.sub('(?<=123)b', '@', text) # outputs 'a123@456c' 
    re.sub('b(?!123)', '@', text) # outputs 'a123@456c' since '456' not match '123'
    re.sub('(?<!123)c', '@', text) # outputs 'a123b456@' 
    

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-11
      • 1970-01-01
      • 2012-07-22
      • 1970-01-01
      • 2015-04-23
      • 2011-01-15
      • 2020-07-03
      • 1970-01-01
      相关资源
      最近更新 更多