我正在编写一个将网址转换为工作链接的函数。这必须转换每个表单:完整网址,如http://link.com
,没有像www.link.com
这样的协议,即使只有link.com
这样的扩展名。
到目前为止,我的功能正在运行,但是当字符串中有多次相同的链接时,会出现一个奇怪的错误。
import re
import cgi
def process_links(string):
"""Convert urls to links in a string"""
# http + https
links = re.findall("(https?://[^\s]+)", string)
# www
links2 = re.findall("(w{3}\.[^\s]+)", string)
# only extension
links3 = re.findall("([^\s]+\.[^\s]{2,})", string)
links = links + links2 + links3
# remove duplicates
links = list(set(links))
string = cgi.escape(string)
for link in links:
# make sure the href attr starts with http|https
if re.match('https?://', link) is None:
http_link = 'http://'+link
else:
http_link = link
htmlLink = '<a href="'+http_link+'">'+link+'</a>'
string = re.sub(link, htmlLink, string)
return string
工作和失败的例子:
# working
string = 'firstlink.com and www.secondlink.com'
# output:
# '<a href="http://firstlink.com">firstlink.com</a> and <a href="http://www.secondlink.com">www.secondlink.com</a>
# failing: when there are several times the same link
string = 'firstlink.com and http://firstlink.com
# output:
# <a href="<a href="http://firstlink.com">http://firstlink.com</a>">firstlink.com</a> and http://<a href="<a href="http://firstlink.com">http://firstlink.com</a>">firstlink.com</a>
我从来没有试过在python中使用正则表达式这个“复杂”,并且无法弄清楚为什么会出现这种奇怪的行为。我认为这来自re.sub()
部分,它可能会取代已被替换的部分?
PS:我的功能可能不是最好的,如果你有任何我正在听的建议,肯定可以改进
答案 0 :(得分:0)
您希望在找到时链接,并使用一个正则表达式查找所有表单。使用re.sub()
和替换函数将是最简单的:
def linkify(match):
link = match.group(1)
http_link = link if re.match('https?://', link) else 'http://' + link
return '<a href="{}">{}</a>'.format(http_link, link)
links = re.compile(r'(https?://[^\s]+|w{3}\.[^\s]+|[^\s]+\.[^\s]{2,})')
string = links.sub(linkify, string)
通过将3个表单组合成一个模式,可以防止多次匹配同一个链接,并且通过使用替换函数,您还可以避免替换使用相同链接的较短形式的多个出现(链接http://firstlink.com
仍然包含firstlink.com
部分以供将来的替换呼叫使用。)
演示:
>>> string = 'firstlink.com and www.secondlink.com'
>>> links.sub(linkify, string)
'<a href="http://firstlink.com">firstlink.com</a> and <a href="http://www.secondlink.com">www.secondlink.com</a>'
>>> string = 'firstlink.com and http://firstlink.com'
>>> links.sub(linkify, string)
'<a href="http://firstlink.com">firstlink.com</a> and <a href="http://firstlink.com">http://firstlink.com</a>'