Python re.sub使用非贪婪模式(.*?)与字符串结束符($)一起使用时,它会变成贪婪模式!

6

代码:

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

预期返回<br><br />A,但实际上返回了一个空字符串''
有什么建议吗?

2
请不要将 str 作为变量名。 - Chris Morgan
1
嗯...嘿...你不是在用正则表达式解析HTML吧? - detly
1
如果你需要解析大量的HTML,那么最好使用像http://www.crummy.com/software/BeautifulSoup/这样的工具,而不是正则表达式。 - Matti Pastell
1
https://dev59.com/X3I-5IYBdhLWcg3wq6do#1732454 - ephemient
2个回答

7
贪心算法是从左到右进行匹配,而不是反过来。它基本上意味着“除非你无法匹配,否则不要匹配”。以下是发生的情况:
1. 正则表达式引擎在字符串开头匹配<br。 2. .*?暂时被忽略,因为它是懒惰的。 3. 尝试匹配>,并成功了。 4. 尝试匹配\w,但失败了。现在有趣了——引擎开始回溯,并看到了.*?规则。在这种情况下,.可以匹配第一个>,所以仍然有希望匹配成功。 5. 这种情况会一直发生,直到正则表达式到达斜杠。然后>\w可以匹配,但$失败了。引擎再次回到懒惰的.*规则,并继续匹配,直到它匹配<br><br />A<br />B。 幸运的是,有一个简单的解决方案:通过替换<br[^>]*>\w$,您不允许在标签外进行匹配,因此它应该替换最后一次出现的匹配。严格来说,这对于HTML并不适用,因为标记属性可能包含>字符,但我假设这只是一个例子。

1

非贪婪模式不会像那样晚启动。它匹配第一个<br,并将以非贪婪方式匹配其余部分,实际上需要到字符串的末尾,因为您指定了$

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

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接