10 Stimmen

URLs in einer Zeichenkette erkennen und mit "<a href..."-Tag einschließen

Ich möchte etwas schreiben, das eigentlich ganz einfach zu sein scheint, aber aus irgendeinem Grund fällt es mir schwer, mich darauf einzulassen.

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

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

Ich danke Ihnen!

1 Stimmen

Können Sie sich wirklich darauf verlassen, dass die URL mit "http" beginnt? Ich sehe sehr oft URLs, die mit "example.com/foo" beginnen. Wollen/müssen Sie auch das übernehmen?

0 Stimmen

Das ist ein wirklich guter Punkt - ich möchte auf jeden Fall sowohl google.com als auch google.de - Ich werde mir die riesige Google-Antwort, die eingereicht wurde, noch einmal ansehen, da sie vielleicht besser geeignet ist.

11voto

tefozi Punkte 5155

Gegoogelte 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: DAVID.mertz@gnosis.cx
             [A-Za-z0-9-]+ # definitely some local user: MERTZ@gnosis.cx
                         @ # ...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 : Angepasst an Ihre Bedürfnisse

11voto

Laurence Gonsalves Punkte 131009

Die "Regex-Magie", die Sie brauchen, ist einfach sub (die eine Ersetzung vornimmt):

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

URL_REGEX könnte etwa so lauten:

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

Dies ist eine ziemlich lockere Regex für URLs: Sie erlaubt mailto-, http- und ftp-Schemata, und danach geht sie so lange weiter, bis sie auf ein "unsicheres" Zeichen stößt (außer Prozent, das Sie für Escapes zulassen wollen). Sie können es strenger machen, wenn Sie es brauchen. Sie könnten zum Beispiel verlangen, dass auf Prozentzeichen ein gültiges Hex-Escape folgt, oder nur ein Pfund-Zeichen (für das Fragment) zulassen oder die Reihenfolge zwischen Abfrageparametern und Fragmenten erzwingen. Dies sollte jedoch für den Anfang genügen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X