Generalmente no tiene nada de malo utilizar librerías de terceros. Te ahorras tiempo, dolores de cabeza, y casos en los que no has pensado. Por ejemplo, enla funcion PHP que muestras, que pasa si le paso un string como este:
<p>http://google.com</p>Te va a devolver esto:
<p><a target="_blank" href="http://google.com</p>">http://google.com
</p></a>
Lo cual obviamente esta rotisimo... E incluso no tenemos que ir tan lejos, basta con que el texto incluya comillas:
Puedes leer más sobre tortugas en "https://es.wikipedia.org/wiki/Testudines"Puedes leer más sobre tortugas en "
<a target="_blank" href="https://es.wikipedia.org/wiki/Testudines"">https://es.wikipedia.org/wiki/Testudines"
</a>
Ahí rompes todo el HTML con una simple camilla doble. Ya que usas ReGeX, te puedes asegurar de capturar solo lo que consideraríamos como una URL valida.
https://regexr.com/3e6m0Eso
sacado de StackOverflow con más de 600 votos.. Y aun así, no es válido porque no aceptaría dominios perfectamente válidos como:
https://hello.amsterdam/
https://barça.cat
http://ñoño.comPorque limita el TLD a un máximo de 6 caracteres y solo espera a-z sin caracteres UTF-8. Tampoco acepta todo mayúsculas...
((http|https)\:\/\/)?[\w0-9\-\.]{1,255}\.[\w]{2,63}(\/[\w_\.\/\#]*)?
Este más o menos cumple con su cometido... Aunque si no lleva http/https delate, habría que ponerlo y eso implica comprobar antes de hacer el replace. En PHP seria algo así:
function makeLinks(string $string): string
{
$regex = '/((http|https)\:\/\/)?[\w0-9\-\.]{1,255}\.[\w]{2,63}(\/[\w_\.\/\#]*)?/iu';
foreach ($output[0] as $link) {
// Comprobar si empieza por http/https
if (strpos($url, 'http://') !== 0 && strpos($url, 'https://') !== 0) { $url = 'http://' . $url;
}
// Creamos un enlace valido manteniendo el formato original.
$anchor = sprintf('<a href="%s" target="_blank">%s</a>', $url, $link); }
return $string;
}
Donde un texto como este:
Puedes leer más sobre tortugas en "https://es.wikipedia.org/wiki/Testudines" y para todo lo demás google.comSe convierte en esto:
Puedes leer más sobre tortugas en "
<a href="https://es.wikipedia.org/wiki/testudines" target="_blank">https://es.wikipedia.org/wiki/Testudines
</a>" y para todo lo demás
<a href="http://google.com" target="_blank">google.com
</a>
Ahora, en javascript hay un problema enorme, hasta ES6 javascript no tenía soporte para unicode en regex. Ende, no podemos utilizar el importantísimo flag /u (unicode) y por lo tanto, no podemos targetear dominios como ñoño.com sin añadir parafernalias como
\0-\t\x0B\f\x0E-\u2027\u202A-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF]) . Hay 3 opciones, o nos saltamos los dominios unicode... no muy recomendable, o solo soportamos navegadores con ES6 (tampoco muy recomendable) o toca transpilar (
https://github.com/mathiasbynens/regexpu ) y con suerte sacar algo funcional…
Yo este paso me lo salto y voy a quitarme unicode de por medio, más que nada para ahorrar tiempo:
function makeLinks(string) {
var regex = /((http|https)\:\/\/)?[\w0-9\-\.]{1,255}\.[\w]{2,63}(\/[\w_\.\/\#]*)?/ig;
var output = string.match(regex);
if (!output || output.length < 1) {
return string;
}
for (var i = 0, t = output.length; i < t; ++i) {
var link = output[i];
var url = link.toLowerCase();
if (!/^https?:\/\//.test(url)) {
url = 'http://' + url;
}
var anchor = '<a href="' + url + '" target="_blank">' + link + '</a>';
string = string.replace(link, anchor);
}
return string;
}
Con ES6 quedaría un poco más bonito:
function makeLinks(string) {
const regex = /((http|https)\:\/\/)?[\w0-9\-\.]{1,255}\.[\w]{2,63}(\/[\w_\.\/\#]*)?/ig;
const output = string.match(regex);
if (!output || output.length < 1) {
return string;
}
output.forEach((link) => {
let url = link.toLowerCase();
url = (!/^https?:\/\//.test(url) ? `http://${url}` : url);
string = string.replace(link, `<a href="${url}" target="_blank">${link}</a>`);
});
return string;
}
console.log(makeLinks('Puedes leer más sobre tortugas en "https://es.wikipedia.org/wiki/Testudines" y para todo lo demás google.com'));
Y todo esto, te lo puedes ahorrar con:
<script src="linkify.min.js"></script>
<script src="linkify-html.min.js"></script>
<script>
console.log(linkifyHtml('Puedes leer más sobre tortugas en "https://es.wikipedia.org/wiki/Testudines" y para todo lo demás google.com', {
className: '',
defaultProtocol: 'http'
}));
</script>
... pero no quieres usar librerías de terceros xD
Saludos