2009-07-01 8 views
6

Yeterince kolay olması gerektiği gibi görünen bir şey yazmak istiyorum ama her ne sebeple kafamı zor bir şekilde geçiriyorum o.Bir dizedeki URL'leri algıla ve "<a href ..." etiketi ile sar

Bir dize iletildiğinde, bu dizeyi HTML'leri URL'leri kodlayarak geçirecek bir python işlevi yazmak istiyorum.

unencoded_string = "This is a link - http://google.com" 

def encode_string_with_links(unencoded_string): 
    # some sort of regex magic occurs 
    return encoded_string 

print encoded_string 

'This is a link - <a href="http://google.com">http://google.com</a>' 

Teşekkür ederiz!

+1

Gerçekten "http" ile başlamak için URL'ye güvenebilir misiniz? Sık sık olmadığı gibi, "example.com/foo" olarak yazılan URL'leri görüyorum. Bunu da eşleştirmek istiyor musun? –

+0

Gerçekten iyi bir nokta - google.com'un yanı sıra http://google.com'u da belirlemek istiyorum. Daha iyi bir uyum sağlayabileceğinden, gönderilen dev google yanıtına ikinci bir göz atacağım. . –

cevap

8

"regex sihirli" İhtiyacınız için Düzeltilmiş sadece sub (a ikame yapar):

def encode_string_with_links(unencoded_string): 
    return URL_REGEX.sub(r'<a href="\1">\1</a>', unencoded_string) 

URL_REGEX şöyle bir şey olabilir:

URL_REGEX = re.compile(r'''((?:mailto:|ftp://|http://)[^ <>'"{}|\\^`[\]]*)''') 

Bu URL'ler için oldukça gevşek bir ifade: mailto, http ve ftp şemalarına izin verir ve bundan sonra hemen hemen "güvensiz" karaktere dönüşene kadar devam eder (izin vermek istediğiniz yüzde hariç) kaçar). İhtiyacın olursa onu daha katı yapabilirsin. Örneğin, yüzdelerin geçerli bir onaltılık kaçışla takip edilmesini veya yalnızca bir pound işaretine (parça için) izin vermesini veya sorgu parametrelerini ve parçaları arasındaki sırayı zorlamanızı gerektirebilir. Yine de başlaman için bu yeterli olmalı.

6

googled çözümleri:

#---------- find_urls.py----------# 
# Functions to identify and extract URLs and email addresses 

import re 

def fix_urls(text): 
    pat_url = re.compile( r''' 
        (?x)(# verbose identify URLs within text 
     (http|ftp|gopher) # make sure we find a resource type 
         :// # ...needs to be followed by colon-slash-slash 
      (\w+[:.]?){2,} # at least two domain groups, e.g. (gnosis.)(cx) 
         (/?| # could be just the domain name (maybe w/ slash) 
       [^ \n\r"]+ # or stuff then space, newline, tab, quote 
        [\w/]) # resource name ends in alphanumeric or slash 
     (?=[\s\.,>)'"\]]) # assert: followed by white or clause ending 
         ) # end of match group 
          ''') 
    pat_email = re.compile(r''' 
        (?xm) # verbose identify URLs in text (and multiline) 
       (?=^.{11} # Mail header matcher 
     (?<!Message-ID:| # rule out Message-ID's as best possible 
      In-Reply-To)) # ...and also In-Reply-To 
        (.*?)(# must grab to email to allow prior lookbehind 
     ([A-Za-z0-9-]+\.)? # maybe an initial part: [email protected] 
      [A-Za-z0-9-]+ # definitely some local user: [email protected] 
         @ # ...needs an at sign in the middle 
       (\w+\.?){2,} # at least two domain groups, e.g. (gnosis.)(cx) 
     (?=[\s\.,>)'"\]]) # assert: followed by white or clause ending 
         ) # end of match group 
          ''') 

    for url in re.findall(pat_url, text): 
     text = text.replace(url[0], '<a href="%(url)s">%(url)s</a>' % {"url" : url[0]}) 

    for email in re.findall(pat_email, text): 
     text = text.replace(email[1], '<a href="mailto:%(email)s">%(email)s</a>' % {"email" : email[1]}) 

    return text 

if __name__ == '__main__': 
    print fix_urls("test http://google.com asdasdasd some more text") 

DÜZENLEME: ihtiyaçlarınız

İlgili konular