Python re.sub 使用非贪婪模式 (.*?) 和字符串结尾 ($) 变成贪婪模式!
代码:
str = '<br><br />A<br />B'
print(re.sub(r'<br.*?>\w$', '', str))
本来应该返回 <br><br />A
,但是却返回了一个空字符串 ''
!
有什么建议吗?
2 个回答
1
这里说的“非贪婪”匹配不会像你想的那样在后面开始。它会先找到第一个 <br
,然后再非贪婪地匹配后面的内容,但实际上这些内容需要匹配到字符串的末尾,因为你指定了 $
。
如果你想让它按你想的那样工作,可以使用
/<br[^<]*?>\w$/
不过,通常不建议用正则表达式来解析HTML,因为某些属性的值里面可能会有 <
或 >
。
7
贪婪匹配是从左到右进行的,反过来就不行。简单来说,就是“除非匹配失败,否则就不匹配”。下面是具体的过程:
- 正则表达式引擎在字符串的开头匹配到
<br
。 .*?
现在被忽略,因为它是懒惰的匹配。- 尝试匹配
>
,成功了。 - 接着尝试匹配
\w
,但失败了。这个时候就有意思了——引擎开始回溯,看到.*?
这个规则。在这种情况下,.
可以匹配第一个>
,所以还有希望能匹配上。 - 这种情况一直持续,直到正则表达式到达斜杠。然后
>\w
可以匹配,但$
失败了。再次,引擎回到懒惰的.*
规则,继续匹配,直到匹配到<br><br />A<br />B
。
幸运的是,有个简单的解决办法:通过替换 <br[^>]*>\w$
,你就不允许在标签外进行匹配,这样就能替换最后一个出现的匹配。
严格来说,这对HTML来说效果不好,因为标签属性中可能包含 >
字符,但我想这只是个例子。