2009-11-13 12 views
7

Korzystanie z Pythona Chcę zamienić wszystkie adresy URL w tekście tekstu na linki do tych adresów URL, na przykład na to, co robi Gmail. Czy można to zrobić w jednym wyrażeń regularnych?Zastąp adresy URL w tekście linkami do adresów URL

Edycja: przez ciało tekstu Chodziło mi zwykły tekst - bez HTML

+1

Można by jednak zakładać, że tworzysz * HTML, ponieważ zwykły tekst nie ma specjalnej notacji o linku a URL. Więc możesz przekonwertować 'http: //blah.com/page/ref/something? Param = foo' znaleziony w twoim zwykłym tekście na' http://blah.com/page/ref/something?param=foo ', tak? – PaulMcG

+0

Tak, zostanie on wstawiony do dokumentu HTML – hoju

+0

, a odpowiedzi na razie koncentrowały się na dopasowaniu adresu URL. Co powiesz na zastąpienie go linkiem? – hoju

Odpowiedz

9

można załadować dokument do góry z DOM/HTML parsowania biblioteki (patrz html5lib), chwycić wszystkie węzły tekstowe, dopasować je przed regularnym ekspresja i wymienić węzły tekstowe z wymianą regex z URI z kotwami wokół niego za pomocą PCRE takich jak:

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

Jestem całkiem pewien, że można biczować przez i znaleźć jakiś mechanizm, który to robi, ja nie mogę myśleć o niczym z mojej głowy.

Edycja: Spróbuj użyć odpowiedź tutaj: 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) 

rozmowę urlify2 na sznurku i myślę, że to wszystko, jeśli nie mamy do czynienia z obiektem DOM.

+0

Co jest niedozwolone w adresie URL? – Amarghosh

+0

Btw, co jeśli link jest już wewnątrz atrybutu href znacznika zakotwiczenia? – Amarghosh

+0

Znajdując się w węźle tekstowym, upewnij się, że element macierzysty lub element nadrzędny nie jest kotwicą. –

0

Gmail jest dużo bardziej otwarty, jeśli chodzi o adresy URL, ale nie zawsze ma rację. na przykład spowoduje to, że www.a.b w hiperłącze, a także http://a.b, często zawodzi, ponieważ zawijany tekst i nietypowe (ale poprawne) znaki URL.

Zobacz appendix A. A. Collected BNF for URI for syntax i użyj tego do zbudowania rozsądnego wyrażenia regularnego, które będzie uwzględniało również to, co otacza adres URL. Dobrze byłoby rozważyć kilka scenariuszy, w których mogą znaleźć się adresy URL.

5

szukałem wokół partii, próbował te rozwiązania i nie był zadowolony z ich czytelności lub funkcji, więc walcowane następujące:

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

Musisz się link na zdjęcie, ale to całkiem proste. Jest to szczególnie przydatne w przypadku przesłanych przez użytkownika tekstów, takich jak komentarze, które, jak zakładam, zazwyczaj dotyczą osób.

+0

Rozejrzałem się również, włączając w to kilka frameworków, które implementowały swoją własną funkcję, i uznałem, że jest to najbardziej czytelna dla nieskomplikowanych celów. – JayD3e

+1

+1 Dzięki za rzucenie tego, uratowałeś mi kłopot =) – mkoistinen