最好的答案是……
不要使用正则表达式
accepted answer 中的表达式漏掉了很多情况。其中,URL 中可以包含 unicode 字符。你想要的正则表达式是here,看了之后,你可能会得出结论,你毕竟不是真的想要它。最正确的版本是一万个字符。
诚然,如果您从包含一堆 URL 的纯非结构化文本开始,那么您可能需要这个 10000 个字符长的正则表达式。但是如果您的输入是结构化的,请使用该结构。您声明的目标是“在锚标记的 href 中提取 url”。当您可以做一些更简单的事情时,为什么还要使用一万个字符长的正则表达式?
改为解析 HTML
对于许多任务,使用Beautiful Soup 会更快更容易使用:
>>> from bs4 import BeautifulSoup as Soup
>>> html = Soup(s, 'html.parser') # Soup(s, 'lxml') if lxml is installed
>>> [a['href'] for a in html.find_all('a')]
['http://example.com', 'http://example2.com']
如果不想使用外部工具,也可以直接使用Python自带的HTML解析库。这是 HTMLParser 的一个非常简单的子类,它完全符合您的要求:
from html.parser import HTMLParser
class MyParser(HTMLParser):
def __init__(self, output_list=None):
HTMLParser.__init__(self)
if output_list is None:
self.output_list = []
else:
self.output_list = output_list
def handle_starttag(self, tag, attrs):
if tag == 'a':
self.output_list.append(dict(attrs).get('href'))
测试:
>>> p = MyParser()
>>> p.feed(s)
>>> p.output_list
['http://example.com', 'http://example2.com']
您甚至可以创建一个接受字符串、调用feed 并返回output_list 的新方法。这是从 html 中提取信息的一种比正则表达式更强大且可扩展的方式。