Python re.sub使用非贪婪模式(。*?)和字符串结尾($)它变得贪婪!

时间:2010-11-25 05:23:37

标签: python regex regex-greedy

代码:

str = '<br><br />A<br />B'
print(re.sub(r'<br.*?>\w$', '', str))

预计会返回<br><br />A,但会返回一个空字符串''

有什么建议吗?

2 个答案:

答案 0 :(得分:6)

贪婪从左到右,但不是。它基本上意味着“除非你没有匹配,否则不匹配”。这是正在发生的事情:

  1. 正则表达式引擎在字符串的开头匹配<br
  2. .*?暂时被忽略,它很懒惰。
  3. 尝试匹配>,然后成功。
  4. 尝试匹配\w并失败。现在它很有趣 - 引擎开始回溯,并看到.*?规则。在这种情况下,.可以匹配第一个>,因此仍有希望进行该匹配。
  5. 这种情况一直持续到正则表达式达到斜线。然后>\w可以匹配,但$失败。同样,引擎返回惰性.*规则,并保持匹配,直到匹配<br><br />A<br />B
  6. 幸运的是,有一个简单的解决方案:通过替换<br[^>]*>\w$,您不会允许在您的代码之外进行匹配,因此它应该替换最后一次出现。
    严格来说,这对HTML不起作用,因为标记属性可以包含>个字符,但我认为它只是一个例子。

答案 1 :(得分:1)

非贪婪不会在以后开始。它与第一个<br匹配,并且非贪婪地匹配其余的,实际上需要转到字符串的末尾,因为您指定了$

要使其按照您想要的方式工作,请使用

/<br[^<]*?>\w$/

但通常情况下,建议不要使用正则表达式来解析HTML,因为某些属性的值可以包含<>