Regex para convertir urls a links

¡Hola!

En el curso de mis viajes, me encontré en una situación en la que tenía que reemplazar URLs obtenidas desde un feed por links a esas URLs. Pensé en crear mi propio código regex, pero al final opté por utilizar google. Hoy me alegro de haberlo hecho, porque me encontré una expresión regular excelente que cubre las urls que veran si clickean este enlace.

Me parece que está muy completo, y hasta ahora no me ha fallado con ninguna url.

El código regex es:

<?php
$regexUrl = "/\b(([\w-]+:\/\/?|www[.]|(\w+\.))([^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|\/))))/";
// $2 = subdomain $3 resto de la url $1 cadena completa

Hice una función que simplifica bastante todo, simplemente hemos de pasarle como parámetro la variable en la que queremos que se transformen las URLs. La dejo a continuación, junto con un ejemplo de su uso. (es muy sencilla de utilizar.)

<?php

function urls_to_links($originalString) {
	return preg_replace("/\b(([\w-]+:\/\/?|(www[.]|\w+\.))([^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|\/))))/", '<a href="http://$3$4">$1</a>', $originalString);
}

$cadena = "esta es una www.match.com con regex.urls.com para transformar a links. Dije alguna vez regex transformar urls? regex.urls.com/transformar/a/links";
$transformada = urls_to_links($cadena);

// ¡la cadena tiene ahora transformados los enlaces!
echo $transformada;

Para aquellos a los que les interese, el test case de esta aplicación es el siguiente:

<?php // regex to transform links test case / regex para transformar urls a enlaces - links test case

$testCases = "http://google.com/mail

http://google.com/mail/

(Something like http://google.com/mail)

http://en.wikipedia.org/wiki/Wikipedia:Manual_of_Style_(disambiguation_pages)

(Something like http://en.wikipedia.org/wiki/Wikipedia:Manual_of_Style_(disambiguation_pages))

http://google.com/mail.


http://google.com/mail/.

<http://google.com/mail>
<http://google.com/mail/>

http://google.com/mail,


http://www.tokyoflash.com/blog/?p=1288.


http://website.ws/faq


http://userid:password@example.com:8080


http://userid@example.com


http://userid@example.com:8080


http://userid:password@example.com

<tag>http://google.com/mail</tag>
Just a www.google.com link.
this is a adsense.google.com
this is a adsense.google.com/
this is a http://adsense.google.com
this is a http://adsense.google.com/";

$testCases = explode("\n", $testCases);

$urlRegex = "/\b(([\w-]+:\/\/?|(www[.]|\w+\.))([^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|\/))))/";
foreach($testCases as $testCase) {
	$stringWithUrls = preg_replace($urlRegex, '<a href="http://$3$4">$1</a>', $testCase);
	echo $stringWithUrls . "<br />";
}

¡Eso sería todo!

Espero que les sea de utilidad, me costó bastante esfuerzo, y modifiqué bastante la expresión original. :)

Un saludo
Pedro

Fuente:
Liberal regex for matching URLs