首页 > 解决方案 > Python re.findall 仅返回第一个匹配项

问题描述

我对此有点坚持,在这里没有发现类似的问题。

我想获取字符串中所有标签元素的列表,例如<a>->a</b>->b

import re

s = '<p><a href="http://www.quackit.com/html/tutorial/html_links.cfm">Example Link</a></p>'
pat = r'<\s*(\w+)/?\s*.*>'
tags = re.findall(pat, s)
print(tags)

结果我得到['p']了这里。如果我将其更改为\w+[a-d]+我就会得到['a']结果。

我希望结果['p', 'a', 'a', 'p']或至少所有不同的标签值。

我在这里做错了什么?谢谢!

使用 Python 3.x

标签: python-3.xregexfindallre

解决方案


首先,您需要使您的模式匹配非贪婪(切换.*.*?)。您可以在 Python文档中给出的示例中阅读更多相关信息(他们甚至使用 HTML 标记作为示例!)。

其次,该/?部分应该在开头,而不是在标签名称之后\w+

此外,第二个\s*是多余的,因为.*也会捕获空格。

import re

s = '<p><a href="http://www.quackit.com/html/tutorial/html_links.cfm">Example Link</a></p>'
pat = r'</?\s*(\w+).*?>'
tags = re.findall(pat, s)
print(tags)

输出:

['p', 'a', 'a', 'p']

对于更通用的解决方案,请考虑使用BeautifulSouporHTMLParser代替:

from html.parser import HTMLParser

class HTMLTagParser(HTMLParser):

    def handle_starttag(self, tag, attrs):
        tags.append(tag)

    def handle_endtag(self, tag):
        tags.append(tag)

s = '<p><a href="http://www.quackit.com/html/tutorial/html_links.cfm">Example Link</a></p>'
tags = []
parser = HTMLTagParser()
parser.feed(s)
print(tags)

输出:

['p', 'a', 'a', 'p']

该方法适用于任意 HTML(因为当您最小化所做的假设时,正则表达式可能会变得混乱)。注意,对于开始标签,attrs参数 inhandle_starttag也可以用来检索标签的属性,如果你需要的话。


推荐阅读