【问题标题】:Python re.sub use non-greedy mode (.*?) with end of string ($) it comes greedy!Python re.sub 使用非贪婪模式 (.*?) 和字符串结尾 ($) 它变得贪婪!
【发布时间】:2011-05-15 12:15:42
【问题描述】:

代码:

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

预计返回&lt;br&gt;&lt;br /&gt;A,但返回的是空字符串''

有什么建议吗?

【问题讨论】:

标签: python regex regex-greedy


【解决方案1】:

贪婪从左到右起作用,但不是。它的基本意思是“除非你不匹配,否则不匹配”。这是发生了什么:

  1. 正则表达式引擎匹配字符串开头的&lt;br
  2. .*? 暂时被忽略了,它很懒。
  3. 尝试匹配&gt;,成功了。
  4. 尝试匹配\w 失败。现在很有趣 - 引擎开始回溯,并看到 .*? 规则。在这种情况下,. 可以匹配第一个 &gt;,因此该匹配仍有希望。
  5. 这种情况一直发生,直到正则表达式到达斜线。然后&gt;\w 可以匹配,但$ 失败。再次,引擎回到惰性.* 规则,并继续匹配,直到匹配&lt;br&gt;&lt;br /&gt;A&lt;br /&gt;B

幸运的是,有一个简单的解决方案:通过替换 &lt;br[^&gt;]*&gt;\w$,您不会允许在标签之外进行匹配,因此它应该替换最后一个匹配项。
严格来说,这对于 HTML 并不适用,因为标签属性可以包含 &gt; 字符,但我认为这只是一个示例。

【讨论】:

    【解决方案2】:

    以后不会这样开始不贪婪。它匹配第一个&lt;br,并将非贪婪匹配其余部分,实际上需要转到字符串的末尾,因为您指定了$

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

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

    但通常不建议使用正则表达式来解析 HTML,因为某些属性的值可以包含 &lt;&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-13
      • 2012-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多