Détecter les URL dans le texte avec JavaScript

151

Quelqu'un a-t-il des suggestions pour détecter les URL dans un ensemble de chaînes?

arrayOfStrings.forEach(function(string){
  // detect URLs in strings and do something swell,
  // like creating elements with links.
});

Mise à jour: J'ai fini par utiliser cette regex pour la détection de lien… Apparemment plusieurs années plus tard.

kLINK_DETECTION_REGEX = /(([a-z]+:\/\/)?(([a-z0-9\-]+\.)+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel|local|internal))(:[0-9]{1,5})?(\/[a-z0-9_\-\.~]+)*(\/([a-z0-9_\-\.]*)(\?[a-z0-9+_\-\.%=&]*)?)?(#[a-zA-Z0-9!$&'()*+.=-_~:@/?]*)?)(\s+|$)/gi

L'assistant complet (avec support optionnel du guidon) est au numéro de référence 1654670 .

arbales
la source
11
Ce n'est probablement pas une bonne idée d'essayer de lister un ensemble fini de TLD, car ils continuent à en créer de nouveaux.
Maxy-B
Se mettre d'accord. Parfois, nous avons besoin d'un code pouvant être mis à jour avec des TLD. En fait, il peut s'agir d'un script de construction pour ajouter un TLD à une expression régulière ou à des TLD de mise à jour de code dynamique dans le code. Il y a des choses dans la vie qui sont censées être standardisées comme les TLD et le fuseau horaire. Un contrôle limité peut être utile pour vérifier l'URL vérifiable des "TLD" existantes pour le cas d'utilisation d'une adresse dans le monde réel.
Edward Chan JW

Réponses:

217

Vous avez d'abord besoin d'une bonne regex qui correspond aux URL. C'est difficile à faire. Voir ici , ici et ici :

... presque tout est une URL valide. Il existe des règles de ponctuation pour le fractionner. En l'absence de ponctuation, vous disposez toujours d'une URL valide.

Vérifiez attentivement la RFC et voyez si vous pouvez construire une URL "invalide". Les règles sont très souples.

Par exemple, :::::une URL valide. Le chemin est ":::::". Un nom de fichier assez stupide, mais un nom de fichier valide.

Est également /////une URL valide. Le netloc ("hostname") est "". Le chemin est "///". Encore une fois, stupide. Aussi valable. Cette URL se normalise à "///" laquelle est l'équivalent.

Quelque chose comme ça "bad://///worse/////" est parfaitement valable. Dumb mais valable.

Quoi qu'il en soit, cette réponse n'est pas destinée à vous donner la meilleure expression régulière, mais plutôt une preuve de la façon de faire la chaîne enveloppant à l'intérieur du texte, avec JavaScript.

OK alors utilisons simplement celui-ci: /(https?:\/\/[^\s]+)/g

Encore une fois, c'est une mauvaise regex . Il aura de nombreux faux positifs. Cependant, c'est assez bon pour cet exemple.

function urlify(text) {
  var urlRegex = /(https?:\/\/[^\s]+)/g;
  return text.replace(urlRegex, function(url) {
    return '<a href="' + url + '">' + url + '</a>';
  })
  // or alternatively
  // return text.replace(urlRegex, '<a href="$1">$1</a>')
}

var text = 'Find me at http://www.example.com and also at http://stackoverflow.com';
var html = urlify(text);

console.log(html)

// html now looks like:
// "Find me at <a href="http://www.example.com">http://www.example.com</a> and also at <a href="http://stackoverflow.com">http://stackoverflow.com</a>"

Donc, en résumé, essayez:

$$('#pad dl dd').each(function(element) {
    element.innerHTML = urlify(element.innerHTML);
});
Croissant frais
la source
4
Quelques exemples des «nombreux faux positifs» amélioreraient grandement cette réponse. Sinon, les futurs Googleurs se retrouvent avec quelques FUD (peut-être valides?).
cmcculloh
Je n'ai jamais su que vous pouviez passer la fonction comme deuxième paramètre pour .replace: |
Aamir Afridi
4
C'est bien, mais il fait la «mauvaise» chose avec des text="Find me at http://www.example.com, and also at http://stackoverflow.com."résultats de ponctuation de fin dans deux 404. Certains utilisateurs en sont conscients et ajouteront un espace après les URL avant la ponctuation pour éviter la rupture, mais la plupart des linkifiers que j'utilise (Gmail, etherpad, phabricator) séparent la ponctuation de fin de l'URL.
skierpage
Si le texte contient déjà une URL ancrée, vous pouvez utiliser la fonction removeAnchors (text) {var div = $ ('<div> </div>') .html (text); div.find ('a'). contents (). unwrap (); return div.text (); } pour supprimer d'abord les ancres avant de retourner text.replace
Muneeb Mirza
Si le texte contient déjà une URL ancrée, vous utilisez jquery pour supprimer l'ancre, mais j'utilise Angular. Comment puis-je supprimer l'ancre dans Angular?
Sachin Jagtap
132

Voici ce que j'ai fini par utiliser comme regex:

var urlRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;

Cela n'inclut pas la ponctuation de fin dans l'URL. La fonction de Crescent fonctionne comme un charme :) donc:

function linkify(text) {
    var urlRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
    return text.replace(urlRegex, function(url) {
        return '<a href="' + url + '">' + url + '</a>';
    });
}
Niaz Mohammed
la source
4
Enfin une regex qui fonctionne vraiment dans les cas les plus évidents! Celui-ci mérite une mise en favori. J'ai testé des milliers d'exemples de recherche sur Google jusqu'à ce que je trouve cela.
Ismael
6
Simple et sympa! Mais le urlRegexdevrait être défini à l' extérieur linkify car la compilation coûte cher.
BM
1
Cela ne parvient pas à détecter l'URL complète: disney.wikia.com/wiki/Pua_(Moana)
Jry9972
1
J'ai ajouté ()dans chaque liste de personnages et cela fonctionne maintenant.
Guillaume F.
3
il ne parvient pas à détecter une URL commençant par www. par ex: www.facebook.com
CraZyDroiD
51

J'ai cherché sur Google ce problème pendant un certain temps, puis il m'est venu à l'esprit qu'il existe une méthode Android, android.text.util.Linkify, qui utilise des expressions régulières assez robustes pour y parvenir. Heureusement, Android est open source.

Ils utilisent quelques modèles différents pour faire correspondre différents types d'URL. Vous pouvez tous les trouver ici: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.0_r1/android/text/util/Regex.java#Regex. 0WEB_URL_PATTERN

Si vous êtes simplement préoccupé par les URL qui correspondent au WEB_URL_PATTERN, c'est-à-dire les URL conformes à la spécification RFC 1738, vous pouvez utiliser ceci:

/((?:(http|https|Http|Https|rtsp|Rtsp):\/\/(?:(?:[a-zA-Z0-9\$\-\_\.\+\!\*\'\(\)\,\;\?\&\=]|(?:\%[a-fA-F0-9]{2})){1,64}(?:\:(?:[a-zA-Z0-9\$\-\_\.\+\!\*\'\(\)\,\;\?\&\=]|(?:\%[a-fA-F0-9]{2})){1,25})?\@)?)?((?:(?:[a-zA-Z0-9][a-zA-Z0-9\-]{0,64}\.)+(?:(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])|(?:biz|b[abdefghijmnorstvwyz])|(?:cat|com|coop|c[acdfghiklmnoruvxyz])|d[ejkmoz]|(?:edu|e[cegrstu])|f[ijkmor]|(?:gov|g[abdefghilmnpqrstuwy])|h[kmnrtu]|(?:info|int|i[delmnoqrst])|(?:jobs|j[emop])|k[eghimnrwyz]|l[abcikrstuvy]|(?:mil|mobi|museum|m[acdghklmnopqrstuvwxyz])|(?:name|net|n[acefgilopruz])|(?:org|om)|(?:pro|p[aefghklmnrstwy])|qa|r[eouw]|s[abcdeghijklmnortuvyz]|(?:tel|travel|t[cdfghjklmnoprtvwz])|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw]))|(?:(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[0-9])))(?:\:\d{1,5})?)(\/(?:(?:[a-zA-Z0-9\;\/\?\:\@\&\=\#\~\-\.\+\!\*\'\(\)\,\_])|(?:\%[a-fA-F0-9]{2}))*)?(?:\b|$)/gi;

Voici le texte intégral de la source:

"((?:(http|https|Http|Https|rtsp|Rtsp):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
+ "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
+ "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
+ "((?:(?:[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}\\.)+"   // named host
+ "(?:"   // plus top level domain
+ "(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])"
+ "|(?:biz|b[abdefghijmnorstvwyz])"
+ "|(?:cat|com|coop|c[acdfghiklmnoruvxyz])"
+ "|d[ejkmoz]"
+ "|(?:edu|e[cegrstu])"
+ "|f[ijkmor]"
+ "|(?:gov|g[abdefghilmnpqrstuwy])"
+ "|h[kmnrtu]"
+ "|(?:info|int|i[delmnoqrst])"
+ "|(?:jobs|j[emop])"
+ "|k[eghimnrwyz]"
+ "|l[abcikrstuvy]"
+ "|(?:mil|mobi|museum|m[acdghklmnopqrstuvwxyz])"
+ "|(?:name|net|n[acefgilopruz])"
+ "|(?:org|om)"
+ "|(?:pro|p[aefghklmnrstwy])"
+ "|qa"
+ "|r[eouw]"
+ "|s[abcdeghijklmnortuvyz]"
+ "|(?:tel|travel|t[cdfghjklmnoprtvwz])"
+ "|u[agkmsyz]"
+ "|v[aceginu]"
+ "|w[fs]"
+ "|y[etu]"
+ "|z[amw]))"
+ "|(?:(?:25[0-5]|2[0-4]" // or ip address
+ "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(?:25[0-5]|2[0-4][0-9]"
+ "|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1]"
+ "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
+ "|[1-9][0-9]|[0-9])))"
+ "(?:\\:\\d{1,5})?)" // plus option port number
+ "(\\/(?:(?:[a-zA-Z0-9\\;\\/\\?\\:\\@\\&\\=\\#\\~"  // plus option query params
+ "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?"
+ "(?:\\b|$)";

Si vous voulez être vraiment sophistiqué, vous pouvez également tester les adresses e-mail. Le regex pour les adresses e-mail est:

/[a-zA-Z0-9\\+\\.\\_\\%\\-]{1,256}\\@[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}(\\.[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25})+/gi

PS: Les domaines de premier niveau pris en charge par l'expression régulière ci-dessus sont à jour en juin 2007. Pour une liste à jour, vous devrez vérifier https://data.iana.org/TLD/tlds-alpha-by-domain.txt .

Adam
la source
3
Étant donné que vous avez une expression régulière insensible à la casse, vous n'avez pas à spécifier a-zA-Zet http|https|Http|Https|rtsp|Rtsp.
Ry-
4
C'est bien, mais je ne suis pas sûr de l'utiliser. Pour la plupart des cas d'utilisation, je préfère accepter certains faux positifs plutôt que d'utiliser une approche reposant sur une liste codée en dur de TLD. Si vous listez des TLD dans votre code, vous garantissez qu'il sera un jour obsolète, et je préfère ne pas intégrer de maintenance future obligatoire dans mon code si je peux l'éviter.
Mark Amery
3
Cela fonctionne 101% du temps, malheureusement, il trouve également des URL qui ne sont pas précédées d'un espace. Si je lance un match sur [email protected], il attrape «mydomain.com». Y a-t-il un moyen d'améliorer cela pour ne l'attraper que s'il a un espace devant lui?
Deminetix
À noter également, c'est parfait pour attraper les URL saisies par les utilisateurs
Deminetix
Notez que grepcode.com n'est plus en place, voici ce que je pense être un lien vers le bon endroit dans le code source Android. Je pense que l'expression régulière utilisée par Android pourrait être mise à jour depuis 2013 (publication d'origine), mais ne semble pas avoir été mise à jour depuis 2015 et peut donc manquer de nouveaux TLD.
James
19

Basé sur la réponse Crescent Fresh

si vous souhaitez détecter des liens avec http: // OU sans http: // et par www. vous pouvez utiliser ce qui suit

function urlify(text) {
    var urlRegex = /(((https?:\/\/)|(www\.))[^\s]+)/g;
    //var urlRegex = /(https?:\/\/[^\s]+)/g;
    return text.replace(urlRegex, function(url,b,c) {
        var url2 = (c == 'www.') ?  'http://' +url : url;
        return '<a href="' +url2+ '" target="_blank">' + url + '</a>';
    }) 
}
h0mayun
la source
C'est une bonne solution, mais je veux aussi vérifier que le texte ne doit pas déjà contenir href. J'ai essayé ce regex = /((?!href)((https?:\/\/)|(www\.)|(mailto:))[^\s </font>+)/gi mais cela ne fonctionne pas. Pouvez-vous m'aider ou pourquoi le regex ci-dessus ne fonctionne pas.
Sachin Jagtap
J'aime que vous ayez également ajouté target = "_ blank" à la sortie renvoyée. Cette version est ce que je voulais. Rien d'extraordinaire (sinon j'utiliserais Linkifyjs) juste assez pour obtenir la plupart des liens.
Michael Kubler
18

Cette bibliothèque sur NPM semble assez complète https://www.npmjs.com/package/linkifyjs

Linkify est un petit plugin JavaScript complet pour trouver des URL en texte brut et les convertir en liens HTML. Il fonctionne avec toutes les URL et adresses e-mail valides.

Dan Kantor
la source
4
Je viens de terminer l'implémentation de linkifyjs dans mon projet et c'est fantastique. Linkifyjs devrait être la réponse à cette question. L'autre à regarder est github.com/twitter/twitter-text
Uber Schnoz
6

La fonction peut également être améliorée pour rendre les images:

function renderHTML(text) { 
    var rawText = strip(text)
    var urlRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;   

    return rawText.replace(urlRegex, function(url) {   

    if ( ( url.indexOf(".jpg") > 0 ) || ( url.indexOf(".png") > 0 ) || ( url.indexOf(".gif") > 0 ) ) {
            return '<img src="' + url + '">' + '<br/>'
        } else {
            return '<a href="' + url + '">' + url + '</a>' + '<br/>'
        }
    }) 
} 

ou pour une image miniature qui renvoie à une image de taille réelle:

return '<a href="' + url + '"><img style="width: 100px; border: 0px; -moz-border-radius: 5px; border-radius: 5px;" src="' + url + '">' + '</a>' + '<br/>'

Et voici la fonction strip () qui pré-traite la chaîne de texte pour l'uniformité en supprimant tout html existant.

function strip(html) 
    {  
        var tmp = document.createElement("DIV"); 
        tmp.innerHTML = html; 
        var urlRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;   
        return tmp.innerText.replace(urlRegex, function(url) {     
        return '\n' + url 
    })
} 
Gautam Sharma
la source
2
let str = 'https://example.com is a great site'
str.replace(/(https?:\/\/[^\s]+)/g,"<a href='$1' target='_blank' >$1</a>")

Short Code Big Work! ...

Résultat:-

 <a href="https://example.com" target="_blank" > https://example.com </a>
Kashan Haider
la source
1

Il existe un package npm existant: url-regex , installez-le simplement avec yarn add url-regexou npm install url-regexet utilisez-le comme suit:

const urlRegex = require('url-regex');

const replaced = 'Find me at http://www.example.com and also at http://stackoverflow.com or at google.com'
  .replace(urlRegex({strict: false}), function(url) {
     return '<a href="' + url + '">' + url + '</a>';
  });
Vedmant
la source
0

tmp.innerText n'est pas défini. Vous devez utiliser tmp.innerHTML

function strip(html) 
    {  
        var tmp = document.createElement("DIV"); 
        tmp.innerHTML = html; 
        var urlRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;   
        return tmp.innerHTML .replace(urlRegex, function(url) {     
        return '\n' + url 
    })
Án Bình Trọng
la source
0

essaye ça:

function isUrl(s) {
    if (!isUrl.rx_url) {
        // taken from https://gist.github.com/dperini/729294
        isUrl.rx_url=/^(?:(?:https?|ftp):\/\/)?(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/i;
        // valid prefixes
        isUrl.prefixes=['http:\/\/', 'https:\/\/', 'ftp:\/\/', 'www.'];
        // taken from https://w3techs.com/technologies/overview/top_level_domain/all
        isUrl.domains=['com','ru','net','org','de','jp','uk','br','pl','in','it','fr','au','info','nl','ir','cn','es','cz','kr','ua','ca','eu','biz','za','gr','co','ro','se','tw','mx','vn','tr','ch','hu','at','be','dk','tv','me','ar','no','us','sk','xyz','fi','id','cl','by','nz','il','ie','pt','kz','io','my','lt','hk','cc','sg','edu','pk','su','bg','th','top','lv','hr','pe','club','rs','ae','az','si','ph','pro','ng','tk','ee','asia','mobi'];
    }

    if (!isUrl.rx_url.test(s)) return false;
    for (let i=0; i<isUrl.prefixes.length; i++) if (s.startsWith(isUrl.prefixes[i])) return true;
    for (let i=0; i<isUrl.domains.length; i++) if (s.endsWith('.'+isUrl.domains[i]) || s.includes('.'+isUrl.domains[i]+'\/') ||s.includes('.'+isUrl.domains[i]+'?')) return true;
    return false;
}

function isEmail(s) {
    if (!isEmail.rx_email) {
        // taken from http://stackoverflow.com/a/16016476/460084
        var sQtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]';
        var sDtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]';
        var sAtom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+';
        var sQuotedPair = '\\x5c[\\x00-\\x7f]';
        var sDomainLiteral = '\\x5b(' + sDtext + '|' + sQuotedPair + ')*\\x5d';
        var sQuotedString = '\\x22(' + sQtext + '|' + sQuotedPair + ')*\\x22';
        var sDomain_ref = sAtom;
        var sSubDomain = '(' + sDomain_ref + '|' + sDomainLiteral + ')';
        var sWord = '(' + sAtom + '|' + sQuotedString + ')';
        var sDomain = sSubDomain + '(\\x2e' + sSubDomain + ')*';
        var sLocalPart = sWord + '(\\x2e' + sWord + ')*';
        var sAddrSpec = sLocalPart + '\\x40' + sDomain; // complete RFC822 email address spec
        var sValidEmail = '^' + sAddrSpec + '$'; // as whole string

        isEmail.rx_email = new RegExp(sValidEmail);
    }

    return isEmail.rx_email.test(s);
}

également reconnaître urls tels que google.com, http://www.google.bla, http://google.bla, www.google.blamais pasgoogle.bla

kofifus
la source
0

Vous pouvez utiliser une expression régulière comme celle-ci pour extraire les modèles d'URL normaux.

(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})

Si vous avez besoin de modèles plus sophistiqués, utilisez une bibliothèque comme celle-ci.

https://www.npmjs.com/package/pattern-dreamer

Kang Andrew
la source
Quel est le but de (?:www\.|(?!www))? Pourquoi devrait wwwww.comêtre invalide?
Toto du
Vous avez raison. En fait, je l'ai juste pris car beaucoup utilisent l'expression régulière. Je recommanderais d'utiliser la bibliothèque liée ci-dessus. Nous devrions considérer de nombreux cas dans la détection d'URL, donc l'expression régulière devrait être plus compliquée.
Kang Andrew
0

Solution orientée objet générique

Pour les gens comme moi qui utilisent des frameworks comme angular qui ne permettent pas de manipuler directement DOM, j'ai créé une fonction qui prend une chaîne et retourne un tableau de url/ plainTextobjets qui peut être utilisé pour créer n'importe quelle représentation d'interface utilisateur que vous voulez.

URL regex

Pour la correspondance d'URL, j'ai utilisé une h0mayunexpression régulière (légèrement adaptée) :/(?:(?:https?:\/\/)|(?:www\.))[^\s]+/g

Ma fonction supprime également les caractères de ponctuation à la fin d'une URL comme .et ,qui, je crois, sera plus souvent une ponctuation réelle qu'une fin d'URL légitime (mais cela pourrait être! Ce n'est pas une science rigoureuse comme d'autres réponses l'expliquent bien) Pour cela, j'applique le suivre l'expression régulière sur les URL correspondantes /^(.+?)([.,?!'"]*)$/.

Code dactylographié

    export function urlMatcherInText(inputString: string): UrlMatcherResult[] {
        if (! inputString) return [];

        const results: UrlMatcherResult[] = [];

        function addText(text: string) {
            if (! text) return;

            const result = new UrlMatcherResult();
            result.type = 'text';
            result.value = text;
            results.push(result);
        }

        function addUrl(url: string) {
            if (! url) return;

            const result = new UrlMatcherResult();
            result.type = 'url';
            result.value = url;
            results.push(result);
        }

        const findUrlRegex = /(?:(?:https?:\/\/)|(?:www\.))[^\s]+/g;
        const cleanUrlRegex = /^(.+?)([.,?!'"]*)$/;

        let match: RegExpExecArray;
        let indexOfStartOfString = 0;

        do {
            match = findUrlRegex.exec(inputString);

            if (match) {
                const text = inputString.substr(indexOfStartOfString, match.index - indexOfStartOfString);
                addText(text);

                var dirtyUrl = match[0];
                var urlDirtyMatch = cleanUrlRegex.exec(dirtyUrl);
                addUrl(urlDirtyMatch[1]);
                addText(urlDirtyMatch[2]);

                indexOfStartOfString = match.index + dirtyUrl.length;
            }
        }
        while (match);

        const remainingText = inputString.substr(indexOfStartOfString, inputString.length - indexOfStartOfString);
        addText(remainingText);

        return results;
    }

    export class UrlMatcherResult {
        public type: 'url' | 'text'
        public value: string
    }
eddyP23
la source
0

Si vous souhaitez détecter des liens avec http: // OU sans http: // OU ftp OU d'autres cas possibles comme la suppression de la ponctuation de fin à la fin, jetez un œil à ce code.

https://jsfiddle.net/AndrewKang/xtfjn8g3/

Un moyen simple d'utiliser cela est d'utiliser NPM

npm install --save url-knife
Kang Andrew
la source