2009-11-13 19 views
7

Verwenden von Python Ich möchte alle URLs in einem Textkörper durch Links zu diesen URLs ersetzen, z. B. was Google Mail tut. Kann dies in einem einlinigen regulären Ausdruck erfolgen?Ersetzen von URLs im Text durch Links zu URLs

Edit: durch Körper von Text, den ich nur Klartext bedeutet - kein HTML

+1

Man würde aber annehmen, dass Sie * HTML * erstellen, da Klartext keine spezielle Notation eines Links im Vergleich zu einer URL hat. Also würden Sie 'http: //blah.com/page/ref/something?param=foo' in Ihrem Text in 'http://blah.com/page/ref/something?param=foo' konvertieren, ja? – PaulMcG

+0

ja, es wird dann in ein HTML-Dokument eingefügt – hoju

+0

die Antworten bisher auf die Übereinstimmung mit der URL konzentriert haben. Wie wäre es, es durch den Link zu ersetzen? – hoju

Antwort

9

Sie das Dokument laden kann mit einem DOM/HTML-Parsing-Bibliothek (siehe html5lib), alle Textknoten greifen, passen sie gegen einen regelmäßigen Ausdruck und die Textknoten mit einem regex Ersatz der URI mit Ankern um es ersetzen eine PCRE mit wie:

/(https?:[;\/?\\@&=+$,\[\]A-Za-z0-9\-_\.\!\~\*\'\(\)%][\;\/\?\:\@\&\=\+\$\,\[\]A-Za-z0-9\-_\.\!\~\*\'\(\)%#]*|[KZ]:\\*.*\w+)/g 

ich bin mir ziemlich sicher, dass Sie geißeln durch und irgendeine Art von Nutzen finden, das dies tut, ich Ich kann mir allerdings nichts vorstellen.

Edit: Versuchen Sie, die Antworten hier mit: How do I get python-markdown to additionally "urlify" links when formatting plain text?

import re 

urlfinder = re.compile("([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}|((news|telnet|nttp|file|http|ftp|https)://)|(www|ftp)[-A-Za-z0-9]*\\.)[-A-Za-z0-9\\.]+):[0-9]*)?/[-A-Za-z0-9_\\$\\.\\+\\!\\*\\(\\),;:@&=\\?/~\\#\\%]*[^]'\\.}>\\),\\\"]") 

def urlify2(value): 
    return urlfinder.sub(r'<a href="\1">\1</a>', value) 

Anruf urlify2 an einer Schnur, und ich denke, dass es, wenn Sie nicht mit einem DOM-Objekt zu tun ist.

+0

Also, was ist in einer URL nicht erlaubt? – Amarghosh

+0

Btw, was ist, wenn der Link bereits innerhalb des href-Attributs eines Anchor-Tags ist? – Amarghosh

+0

Wenn Sie sich innerhalb des Textknotens befinden, stellen Sie sicher, dass der Eltern- oder Vorfahrknoten kein Anker ist. –

0

Wenn Sie "Textkörper" sagen, meinen Sie eine einfache Textdatei oder einen Fließtext in einem HTML-Dokument? Wenn Sie das HTML-Dokument möchten, verwenden Sie , um es zu analysieren; Durchsuchen Sie dann den Fließtext und fügen Sie die Tags ein.

Das Abstimmen der tatsächlichen URLs ist wahrscheinlich am besten mit dem Modul urlparse möglich. Vollständige Diskussion hier: How do you validate a URL with a regular expression in Python?

0

Gmail ist viel offener, wenn es um URLs geht, aber es ist auch nicht immer richtig. z.B. Es macht www.a.b zu einem Hyperlink und http://a.b, aber es scheitert häufig aufgrund von umgebrochenem Text und ungewöhnlichen (aber gültigen) URL-Zeichen.

Siehe appendix A. A. Collected BNF for URI for syntax, und verwenden Sie das, um einen vernünftigen regulären Ausdruck zu erstellen, der berücksichtigt, was die URL ebenfalls umgibt. Es empfiehlt sich, einige Szenarien in Betracht zu ziehen, in denen URLs möglicherweise enden.

1
/\w+:\/\/[^\s]+/ 
5

ich gejagt viel herum, versucht, diese Lösungen und war mit ihrer Lesbarkeit oder Funktionen, die nicht glücklich, so rollte ich folgendes:

_urlfinderregex = re.compile(r'http([^\.\s]+\.[^\.\s]*)+[^\.\s]{2,}') 

def linkify(text, maxlinklength): 
    def replacewithlink(matchobj): 
     url = matchobj.group(0) 
     text = unicode(url) 
     if text.startswith('http://'): 
      text = text.replace('http://', '', 1) 
     elif text.startswith('https://'): 
      text = text.replace('https://', '', 1) 

     if text.startswith('www.'): 
      text = text.replace('www.', '', 1) 

     if len(text) > maxlinklength: 
      halflength = maxlinklength/2 
      text = text[0:halflength] + '...' + text[len(text) - halflength:] 

     return '<a class="comurl" href="' + url + '" target="_blank" rel="nofollow">' + text + '<img class="imglink" src="/images/linkout.png"></a>' 

    if text != None and text != '': 
     return _urlfinderregex.sub(replacewithlink, text) 
    else: 
     return '' 

Sie erhalten eine Verbindung aus Bild erhalten müssen, aber das ist ziemlich einfach. Dies ist speziell für Benutzer eingereicht Text wie Kommentare, die ich normalerweise davon ausgehe, was Menschen beschäftigen.

+0

Ich schaute mich auch um, einschließlich einiger Frameworks, die ihre eigene linkify-Funktion implementierten, und ich fand, dass diese für nicht-komplexe Zwecke am besten lesbar ist. – JayD3e

+1

+1 Danke für das Rollen dieses, rettete mir das Problem =) – mkoistinen

Verwandte Themen