2009-07-01 6 views
6

Ich möchte etwas schreiben, das so aussieht, als ob es einfach genug sein sollte, aber aus irgendeinem Grund habe ich es schwer, mich umzusehen es.URLs in einer Zeichenfolge erkennen und mit dem Tag "<a href ..." umhüllen

Ich bin auf der Suche nach einer Python-Funktion, die, wenn eine Zeichenfolge übergeben wird, diese Zeichenfolge mit HTML-Codierung um URLs zurückgibt.

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

Vielen Dank!

+1

Können Sie sich wirklich darauf verlassen, dass die URL mit "http" beginnt? So oft wie nicht, sehe ich URLs als "example.com/foo" geschrieben. Willst du das auch? –

+0

Das ist ein wirklich guter Punkt - ich möchte google.com genauso gut finden wie http://google.com - Ich werde einen Blick auf die riesige Google-Antwort werfen, die eingereicht wurde, da dies vielleicht besser passt . –

Antwort

8

Die "regex Magie" Sie brauchen, ist nur sub (was tut eine Substitution):

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

URL_REGEX könnte etwas wie:

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

Dies ist eine ziemlich lockere Regex für URLs: Es ermöglicht Mailto, http und FTP-Schemas, und danach geht so ziemlich weiter, bis es in einem "unsicheren" Zeichen (außer Prozent, die Sie berücksichtigen möchten) entkommt). Sie könnten es strenger machen, wenn Sie müssen. Sie können beispielsweise verlangen, dass auf Prozente ein gültiger Hex-Escape folgen oder nur ein Pfundzeichen (für das Fragment) oder die Reihenfolge zwischen Abfrageparametern und Fragmenten erzwingen. Dies sollte jedoch ausreichen, um Ihnen den Einstieg zu erleichtern.

6

gegoogelt Lösungen:

#---------- 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") 

EDIT: auf Ihre Bedürfnisse abgestimmt

Verwandte Themen