【问题标题】:Why does this regex not work: r'.*logo.*' [duplicate]为什么这个正则表达式不起作用:r'.*logo.*' [重复]
【发布时间】:2014-03-08 11:46:25
【问题描述】:

我希望以下正则表达式能够匹配,但事实并非如此。为什么?

import re
html = '''
                <a href="#">
                    <img src="logo.png" alt="logo" width="100%">
                    </img>
                 </a>
  '''
m = re.match( r'.*logo.*', html, re.M|re.I)

if m: 
    print m.group(1)
if not m:
    print "not found"

【问题讨论】:

标签: python regex string


【解决方案1】:

使用re.searchre.match 假定匹配在字符串的开头。

【讨论】:

  • ...好吧,可以说,.* 应该允许它无论如何匹配,re.MULTILINE 正在使用中。
  • 好的,如果这不是问题,那是什么?
  • 这是一个很好的问题,如果我知道(或者,好吧,有时间/有重现的意愿),我会自己发布一个答案。 :)
  • 已回答 -- 除了 re.MULTILINE 之外,还需要 re.DOTALL 才能使前导 .* 匹配换行符。
【解决方案2】:

我们不使用正则表达式来解析 HTML。

在我之后重复:我们不使用正则表达式来解析 HTML。

也就是说,它不起作用,因为re.match 明确地只检查行的开头。请改用re.searchre.findall

【讨论】:

  • 推荐靓汤。
  • 这个答案比我的好,因为它找到了问题的根源。
  • (在 SO 上获得声誉的最快方法?告诉别人不要使用正则表达式来解析 HTML。)
  • @Mr.Polywhirl,Beautiful Soup 现在只是 lxml.html 的包装;为什么不直接使用真正的底层库(可以说设计更好一些)?
  • 啊,明白了——re.DOTALL 是前导 .* 匹配换行所必需的。现在这是有道理的。
【解决方案3】:

您需要包含 re.DOTALL (== re.S) 标志以允许 .匹配换行符 (\n)。

但是,如果“logo”出现在其中的任何位置,则返回整个文档;用处不大。

稍微好一点是

import re
html = """
    <a href="#">
        <img src="logo.png" alt="logo" width="100%" />
    </a>
"""

match_logo = re.compile(r'<[^<]*logo[^>]*>', flags = re.I | re.S)

for found in match_logo.findall(html):
    print(found)

返回

<img src="logo.png" alt="logo" width="100%" />

会更好

from bs4 import BeautifulSoup

pg = BeautifulSoup(html)
print pg.find("img", {"alt":"logo"})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-05
    相关资源
    最近更新 更多