2013-06-04 57 views
0

我正在寫一個函數來將URL轉換爲工作鏈接。這必須轉換每種形式:像http://link.com的完整url,沒有像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

第一次循環,應用re.sub將*替換firstlink.com的所有*出現與firstlink.com,並通過第二次循環時,應用re.sub將取代*所有*發生http://firstlink.com與http://firstlink.com

回答

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>' 
+0

謝謝,我試圖使用編譯方法,但無法讓它工作 – romainberger