3

我无法弄清楚如何为我的生活进行多次环视。假设我想匹配散列后的可变数量的数字,但如果前面有某些东西或后面有其他东西,则不匹配。例如我想在下面匹配#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)
4

1 回答 1

3

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

#12

这就是发生的事情:

引擎检查两个lookbehinds - 他们不匹配,所以它继续捕获组#[0-9]+和matches #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包裹。)

于 2013-04-25T00:58:26.000 回答