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?
我对此有些困惑,在这里没有发现类似的问题。
我想获取字符串中所有标签元素的列表,例如<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?