Python re.findall returns 仅第一个匹配

Python re.findall returns only first match

我对此有些困惑,在这里没有发现类似的问题。

我想获取字符串中所有标签元素的列表,例如<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 docs 中给出的示例中阅读更多相关信息(他们甚至使用 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']

对于更通用的解决方案,请考虑改用 BeautifulSoup or HTMLParser

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(因为正则表达式在您最小化假设时会变得混乱)。请注意,对于开始标记,handle_starttag 中的 attrs 参数也可用于检索标记的属性,如果您需要的话。

使用或 (|) 运算符并记下由运算符分隔的两个模式,应该可以。

参考这个, How is the AND/OR operator represented as in Regular Expressions?