多个否定先行断言

时间:2013-04-25 00:53:19

标签: python regex

我无法弄清楚如何为我的生活做多次寻找。假设我想在哈希之后匹配可变数量的数字,但如果前面有某些内容或者后面跟着其他内容则不匹配。例如,我想在下面匹配#123或#12345。外观似乎很好,但前瞻不是。我没有想法。

matches = ["#123", "This is #12345",
           # But not
           "bad #123", "No match #12345", "This is #123-ubuntu", 
           "This is #123 0x08"]

pat = '(?<!bad )(?<!No match )(#[0-9]+)(?! 0x0)(?!-ubuntu)'

for i in matches:
    print i, re.search(pat, i)

1 个答案:

答案 0 :(得分:3)

你也应该看一下捕捉。我打赌你会得到最后两个字符串:

#12

这就是:

引擎检查两个lookbehinds - 它们不匹配,因此继续捕获组#[0-9]+并匹配#123。现在它检查前瞻。他们失败了。但现在有回溯!模式中有一个变量,即+。因此引擎会丢弃最后一个匹配的字符(3)并再次尝试。现在,前瞻不再是问题,你得到一个匹配。解决此问题的最简单方法是添加另一个前瞻,确保您转到最后一位:

pat = r'(?<!bad )(?<!No match )(#[0-9]+)(?![0-9])(?! 0x0)(?!-ubuntu)'

注意使用原始字符串(前导r) - 在这种模式中无关紧要,但这通常是一种很好的做法,因为一旦你开始转义字符,事情会变得很难看。

编辑:如果您正在使用或愿意使用regex软件包而不是re,那么您将获得抑制回溯的占有量词:

pat = r'(?<!bad )(?<!No match )(#[0-9]++)(?! 0x0)(?!-ubuntu)'

这取决于您发现哪些更易读或可维护。不过,后者的效率会略高一些。 (积分转到nhahtdh指我到regex包。)