否定前瞻与正向前瞻语法

时间:2016-04-06 19:24:22

标签: regex lookahead negative-lookahead

给出以下文字:

  

我的名字是foo。

     

我的名字是吧。

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

Postive lookahead:^(?=.*bar).*$返回My name is bar.

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

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

2 个答案:

答案 0 :(得分:3)

负向前瞻需要嵌套在多组括号内,限定符为SomeClass someClass = (SomeClass)combobox.SelectedItem; ,量词. 称为淬火贪婪令牌。在这种情况下,您不必使用它。

您可以使用在开头处锚定的正常预测而不是tempered greedy token

*

请参阅regex demo

下面,

  • ^(?!.*foo).*$ - 匹配字符串开头的位置
  • ^ - 如果行上某处有(?!.*foo)(或foo模式启用时为字符串),则表示匹配失败;
  • DOTALL - 任意0个字符(如果.*$模式已关闭,则为换行符),直至字符串/行的末尾。

使用什么?

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

答案 1 :(得分:0)

示例

给出字符串text = 'a123b456c',我们要替换子字符串'123'

(?=123) Positive lookahead:    Matches substring '123' *forward* but not replaced 
(?<=123) Positive lookbehind:  Matches substring '123' *backward* but not replaced
(?!123) Negative lookahead:    Substring not match '123' *forward* and not replaced 
(?<!123) Negative lookbehind:  Substring not match '123' *backward* and not replaced

也看不到它是如何工作的:

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@' 

希望这会有所帮助