为啥这个正则表达式不起作用:r'.*logo.*' [重复]

Posted

技术标签:

【中文标题】为啥这个正则表达式不起作用:r\'.*logo.*\' [重复]【英文标题】: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"  >
                    </img>
                 </a>
  '''
m = re.match( r'.*logo.*', html, re.M|re.I)

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

【问题讨论】:

另见***.com/a/1732454/14122 【参考方案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"   />
    </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"   />

会更好

from bs4 import BeautifulSoup

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

【讨论】:

以上是关于为啥这个正则表达式不起作用:r'.*logo.*' [重复]的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个 C# 正则表达式不起作用?

为啥当 CLOB 大小 > 4KB 时这个简单的正则表达式不起作用?

为啥我的产品代码的正则表达式不起作用? [关闭]

为啥正则表达式不起作用

为啥我的正则表达式组量词不起作用?

为啥 `\d` 在 sed 的正则表达式中不起作用? [复制]