Sustituir URLs por links con php

Tras mucho googlear y no encontrar ninguna función que buscase las urls correctamente superé mi vagancia natural y me decidí a crearla yo mismo copiando el comportamiento de twitter al poner urls en los tweets. La podéis ver funcionando en mi página TGMF en los comentarios de las fotos.

El resultado fue este:

1
2
3
4
5
6
7
8
function searchLinks($cadena){
  $cadena = " ".$cadena." ";
  $cadena = ereg_replace('([^a-zA-Z0-9@/."])(www.)([a-zA-Z0-9]{1}(\.*[_0-9a-zA-Z-]+)+\.{1}[a-zA-Z]{2,4})(/[-a-zA-Z0-9%_+.~#?&//=]+)*(:[0-9]+)*([^a-zA-Z0-9@])', '\1\3\5\7', $cadena);
  $cadena = ereg_replace('([^a-zA-Z0-9@/."])([a-zA-Z0-9]{1}[_0-9a-zA-Z-]+\.{1})([a-zA-Z]{1}(\.*[_0-9a-zA-Z-]+)+\.{1}[a-zA-Z]{2,4})(/[-a-zA-Z0-9%_+.~#?&//=!]+)*(:[0-9]+)*([^a-zA-Z0-9@])', '\1\2\3\5\7', $cadena);
  $cadena = ereg_replace('([^a-zA-Z0-9@/."])([a-zA-Z0-9]{1}(\.*[_0-9a-zA-Z-]+)+\.{1}[a-zA-Z]{2,4})(/[-a-zA-Z0-9%_+.~#?&//=]+)+(:[0-9]+)*([^a-zA-Z0-9@])', '\1\2\4\6', $cadena);
  $cadena = ereg_replace('([^a-zA-Z0-9@/."])(http://|ftp://|https://|ftps://)(www.)*([a-zA-Z0-9]{1}(\.*[_0-9a-zA-Z-]+)+\.{1}[a-zA-Z]{2,4})(/[-a-zA-Z0-9%_+.~#?&//=!]+)*(:[0-9]+)*([^a-zA-Z0-9])', '\1\4\6\8', $cadena);
  return trim($cadena);
}

Forma de uso de la función, pasas una cadena de texto y la devuelve con las etiquetas HTML de los links.

Lo primero que hace la función es añadir un espacio al principio y al final de la cadena ya que en cualquiera de los cuatro supuestos para ser considerado el fragmento una url debe comenzar por «algo» que no sea una letra, un número, una arroba, una barra diagonal o un punto. Al final se eliminarán con trim() antes de devolver la cadena transformada.

Después, mediante expresiones regulares comprueba que en el texto que pasamos a la función esté alguno de los 4 supuestos y los sustituye por un enlace HTML.

  • 1º supuesto: La url empieza por www. Este supuesto lo distinguimos de un simple subdominio para poder eliminar las www al mostrar la url.
  • 2º supuesto: La url empieza por un subdominio.
  • 3º supuesto: La url es un dominio sin subdominios.
  • 4º supuesto: La url empieza por http://, https://, ftp:// o ftps://. En este supuesto se añade la condición de que no empiece por comillas, para diferenciarlo de los enlaces incluidos por la función con la etiqueta a href.

En todos los supuestos:

  • El dominio debe estar compuesto por caracteres alfanuméricos y guiones y debe empezar por un carácter alfanumérico.
  • El dominio debe acabar por un punto y de 2 a 4 letras (los dominios de segundo nivel son considerados un dominio de primer nivel con un subdominio por la función).
  • El dominio puede estar seguido de barras diagonales y caracteres alfanuméricos y guiones.
  • Y puede terminar por dos puntos y un número para indicar un puerto concreto (Este puerto se oculta al mostrar la dirección).

La función tiene un «problema», uso ereg_replace() que esta marcada como deprecated desde PHP 5.3.0. Si alguien quiere modificar las expresiones regulares para que sean compatibles con PCRE (Expresiones regulares compatibles con PERL) para poder utilizar la función preg_replace() que lo ponga en los comentarios. Toda ayuda para perfeccionar la función será bien recibida.

Con esto termina la primera entrada con chicha de ScaryPenguin. Si algo no queda claro o me he dejado de explicar alguna cosa para eso están los comentarios.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.