如何确保 re.findall() 停在正确的位置?

Posted

技术标签:

【中文标题】如何确保 re.findall() 停在正确的位置?【英文标题】:How do I ensure that re.findall() stops at the right place? 【发布时间】:2013-07-19 21:40:13 【问题描述】:

这是我的代码:

a='<title>aaa</title><title>aaa2</title><title>aaa3</title>'
import re
re.findall(r'<(title)>(.*)<(/title)>', a)

结果是:

[('title', 'aaa</title><title>aaa2</title><title>aaa3', '/title')]

如果我曾经设计过一个爬虫来获取网站的标题,我最终可能会得到类似这样的东西,而不是网站的标题。

我的问题是,如何将findall 限制为单个&lt;title&gt;&lt;/title&gt;

【问题讨论】:

你可以使用 BeautifulSoup 代替 Regex 来解析 html ***.com/a/1732454/193892 【参考方案1】:
re.findall(r'<(title)>(.*?)<(/title)>', a)

*之后添加?,这样就不会贪心了。

【讨论】:

【参考方案2】:

如果您只想要一个匹配项,请使用 re.search 而不是 re.findall

>>> s = '<title>aaa</title><title>aaa2</title><title>aaa3</title>'
>>> import re
>>> re.search('<title>(.*?)</title>', s).group(1)
'aaa'

如果您想要所有标签,那么您应该考虑将其更改为非贪婪(即 - .*?):

print re.findall(r'<title>(.*?)</title>', s)
# ['aaa', 'aaa2', 'aaa3']     

但真的可以考虑使用 BeautifulSoup 或 lxml 或类似的东西来解析 HTML。

【讨论】:

确实,使用正则表达式解析 HTML 或 XML 通常是个坏主意。【参考方案3】:

改用非贪婪搜索:

r'<(title)>(.*?)<(/title)>'

问号表示匹配尽可能少的字符。现在您的 findall() 将返回您想要的每个结果。

http://docs.python.org/2/howto/regex.html#greedy-versus-non-greedy

【讨论】:

【参考方案4】:

使用 BeautifulSoup 模块会容易得多。

https://pypi.python.org/pypi/beautifulsoup4

【讨论】:

以上是关于如何确保 re.findall() 停在正确的位置?的主要内容,如果未能解决你的问题,请参考以下文章

python 正则(re.compile()/re.findall())

re.findall 行为怪异

re.findall 行为怪异

re.findall 行为怪异

re.findall 行为怪异

re正则匹配