2009-11-13 14 views
7

Usar Python Quiero reemplazar todas las URL en un cuerpo de texto con enlaces a esas URL, como lo hace Gmail. ¿Se puede hacer esto en una expresión regular de un trazador de líneas?reemplazar URLs en texto con enlaces a URL

Editar: por el cuerpo del texto que sólo la intención de texto plano - sin HTML

+1

Uno supondría, sin embargo, que está * creando * HTML, ya que el texto sin formato no tiene una notación especial de un enlace frente a una URL. Entonces, convertirías 'http: //blah.com/page/ref/something? Param = foo' en tu texto simple a' http://blah.com/page/ref/something?param=foo ', ¿sí? – PaulMcG

+0

sí, luego se insertará en un documento HTML – hoju

+0

, las respuestas hasta ahora se han centrado en hacer coincidir la URL. ¿Qué hay de reemplazarlo con el enlace? – hoju

Respuesta

9

Puede cargar el documento con una biblioteca DOM/análisis de HTML (ver html5lib), agarrar todos los nodos de texto, coincide con ellos contra un habitual expresión y sustituir a los nodos de texto con un reemplazo de expresiones regulares de la URI con anclajes alrededor de ella utilizando un PCRE tales como:

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

estoy bastante seguro de que puede azotar a través y encontrar algún tipo de utilidad que hace esto, Sin embargo, no puedo pensar en ninguno de mi cabeza.

Editar: Trate de usar las respuestas aquí: 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) 

urlify2 llamada en una cadena y creo que eso es todo si no se trata de un objeto DOM.

+0

Entonces, ¿qué no está permitido en una url? – Amarghosh

+0

Por cierto, ¿y si el enlace ya está dentro del atributo href de una etiqueta de anclaje? – Amarghosh

+0

Cuando se encuentre dentro del nodo de texto, asegúrese de que el padre o ancestro no sea un delimitador. –

0

Gmail es mucho más abierto, cuando se trata de URL, pero tampoco siempre es correcto. p.ej. hará que www.a.b se convierta en un hipervínculo además de http://a.b, pero a menudo falla debido a texto envolvente y caracteres de URL poco comunes (pero válidos).

Consulte appendix A. A. Collected BNF for URI for syntax, y úselo para crear una expresión regular razonable que considere lo que rodea a la URL también. Le recomendamos que considere un par de escenarios donde las URL pueden terminar.

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

cacé alrededor de un lote, trataron estas soluciones y no estaba contento con su legibilidad o características, por lo que rodó el siguiente:

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

que necesitará para conseguir un enlace desde la imagen, pero eso es bastante fácil. Esto es específicamente para el texto enviado por el usuario, como los comentarios, que supongo que suele ser a lo que se enfrentan las personas.

+0

Miré a mi alrededor también, incluyendo algunos frameworks que implementaron su propia función de enlace, y encontré que este es el más legible para fines no complejos. – JayD3e

+1

+1 Gracias por rodar esto, me salvó el problema =) – mkoistinen

Cuestiones relacionadas