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
jaja me encanta como me decis al final "pero no quieres usar librerias de terceros" jaja... no, el tema es que las liberias de terceros (no se si todas) te ofrecen más cosas de las que quizás en mi proyecto necesito... yo se que jquery es una libreria de terceros que ofrece más cosas por ahí que yo vaya a necesitar pero es diferente... veo que es muy engorroso esto de detectar una url plana y pasarla a html y no me va a quedar de otra que usar linkify xD pero no porque no use... uso si no hay más remedio..