Erkennen Sie URLs im Text mit JavaScript

151

Hat jemand Vorschläge zum Erkennen von URLs in einer Reihe von Zeichenfolgen?

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

Update: Ich habe diesen regulären Ausdruck zur Linkerkennung verwendet ... Anscheinend einige Jahre später.

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

Der vollständige Helfer (mit optionaler Lenkerunterstützung ) befindet sich unter der Nummer 1654670 .

Arbales
quelle
11
Es ist wahrscheinlich keine gute Idee, einen endlichen Satz von TLDs aufzulisten, da sie ständig neue erstellen.
Maxy-B
Zustimmen. Manchmal benötigen wir aktualisierbaren Code mit TLDs. Tatsächlich kann ein Skript zum Anhängen von TLDs an Regex- oder dynamische Code-Aktualisierungs-TLDs im Code erstellt werden. Es gibt Dinge im Leben, die standardisiert werden sollen, wie TLDs und Zeitzonen. Eine endliche Kontrolle kann hilfreich sein, um vorhandene überprüfbare "TLDs" -URLs für den Anwendungsfall der realen Adressadresse zu überprüfen.
Edward Chan JW

Antworten:

217

Zuerst benötigen Sie eine gute Regex, die mit URLs übereinstimmt. Das ist schwer zu machen. Sehen Sie hier , hier und hier :

... fast alles ist eine gültige URL. Es gibt einige Interpunktionsregeln für die Aufteilung. Ohne Interpunktion haben Sie immer noch eine gültige URL.

Überprüfen Sie den RFC sorgfältig und prüfen Sie, ob Sie eine "ungültige" URL erstellen können. Die Regeln sind sehr flexibel.

Zum Beispiel :::::ist eine gültige URL. Der Weg ist ":::::". Ein ziemlich dummer Dateiname, aber ein gültiger Dateiname.

Auch /////ist eine gültige URL. Das Netloc ("Hostname") ist "". Der Weg ist "///". Wieder dumm. Auch gültig. Diese URL normalisiert sich zu "///" der entsprechenden URL .

So etwas "bad://///worse/////" ist vollkommen gültig. Dumm aber gültig.

Wie auch immer, diese Antwort soll Ihnen nicht den besten regulären Ausdruck geben, sondern vielmehr einen Beweis dafür, wie der String mit JavaScript in den Text gewickelt wird.

OK, also lass uns einfach dieses verwenden: /(https?:\/\/[^\s]+)/g

Auch dies ist eine schlechte Regex . Es wird viele Fehlalarme geben. Für dieses Beispiel ist es jedoch gut genug.

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>"

Also in Summe versuchen:

$$('#pad dl dd').each(function(element) {
    element.innerHTML = urlify(element.innerHTML);
});
Halbmond frisch
quelle
4
Einige Beispiele für die "vielen Fehlalarme" würden diese Antwort erheblich verbessern. Ansonsten bleibt zukünftigen Googlern nur eine (vielleicht gültige?) FUD übrig.
cmcculloh
Ich wusste nie, dass Sie die Funktion als zweiten Parameter für Folgendes übergeben können .replace: |
Aamir Afridi
4
Es ist gut, aber es macht das "Falsche" mit nachgestellten Interpunktionen, die text="Find me at http://www.example.com, and also at http://stackoverflow.com."zu zwei 404 führen. Einige Benutzer sind sich dessen bewusst und fügen vor der Interpunktion ein Leerzeichen nach den URLs ein, um einen Bruch zu vermeiden. Die meisten von mir verwendeten Linkifizierer (Google Mail, Etherpad, Phabricator) trennen die nachfolgende Interpunktion von der URL.
Skifahrerseite
Falls der Text bereits eine verankerte URL enthält, können Sie die Funktion removeAnchors (Text) verwenden. {Var div = $ ('<div> </ div>') .html (Text); div.find ('a'). content (). unwrap (); return div.text (); }, um zuerst Anker zu entfernen, bevor Sie text.replace zurückgeben
Muneeb Mirza
Wenn der Text bereits eine verankerte URL enthält, verwenden Sie jquery, um den Anker zu entfernen, aber ich verwende Angular. Wie kann ich den Anker in Angular entfernen?
Sachin Jagtap
132

Folgendes habe ich letztendlich als Regex verwendet:

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

Dies beinhaltet keine nachgestellte Interpunktion in der URL. Die Funktion von Crescent funktioniert wie ein Zauber :) Also:

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
quelle
4
Endlich eine Regex, die im offensichtlichsten Fall wirklich funktioniert! Dieser verdient ein Lesezeichen. Ich habe Tausende Beispiele aus der Google-Suche getestet, bis ich diese gefunden habe.
Ismael
6
Einfach und nett! Aber das urlRegexsollte außerhalb definiert werden, linkifyda das Kompilieren teuer ist.
BM
1
Dies erkennt
Jry9972
1
Ich habe ()in jeder Liste von Zeichen hinzugefügt und es funktioniert jetzt.
Guillaume F.
3
Es wird keine URL erkannt, die mit nur www beginnt. Zum Beispiel: www.facebook.com
CraZyDroiD
51

Ich habe dieses Problem eine ganze Weile gegoogelt, dann kam mir der Gedanke, dass es eine Android-Methode gibt, android.text.util.Linkify, die einige ziemlich robuste reguläre Ausdrücke verwendet, um dies zu erreichen. Zum Glück ist Android Open Source.

Sie verwenden einige verschiedene Muster, um verschiedene Arten von URLs abzugleichen. Sie finden sie alle hier: 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

Wenn Sie sich nur Gedanken über URLs machen, die mit WEB_URL_PATTERN übereinstimmen, dh URLs, die der RFC 1738-Spezifikation entsprechen, können Sie Folgendes verwenden:

/((?:(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;

Hier ist der vollständige Text der Quelle:

"((?:(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|$)";

Wenn Sie wirklich ausgefallen sein möchten, können Sie auch nach E-Mail-Adressen suchen. Der reguläre Ausdruck für E-Mail-Adressen lautet:

/[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: Die von der obigen Regex unterstützten Top-Level-Domains sind ab Juni 2007 aktuell. Eine aktuelle Liste finden Sie unter https://data.iana.org/TLD/tlds-alpha-by-domain.txt .

Adam
quelle
3
Da Sie einen Groß- und Kleinschreibung regulären Ausdruck haben, müssen Sie nicht angeben a-zA-Zund http|https|Http|Https|rtsp|Rtsp.
Ry-
4
Das ist schön, aber ich bin mir nicht sicher, ob ich es jemals benutzen würde. In den meisten Anwendungsfällen würde ich lieber einige Fehlalarme akzeptieren, als einen Ansatz zu verwenden, der auf einer fest codierten Liste von TLDs beruht. Wenn Sie TLDs in Ihrem Code auflisten, garantieren Sie, dass sie eines Tages veraltet sein werden, und ich möchte lieber keine obligatorische zukünftige Wartung in meinen Code einbauen, wenn ich dies vermeiden kann.
Mark Amery
3
Dies funktioniert in 101% der Fälle. Leider werden auch URLs gefunden, denen kein Leerzeichen vorangestellt ist. Wenn ich ein Match auf [email protected] starte, fängt es 'mydomain.com'. Gibt es eine Möglichkeit, dies zu verbessern, um es nur zu fangen, wenn es ein Leerzeichen vor sich hat?
Deminetix
Zu beachten ist auch, dass dies perfekt ist, um vom Benutzer eingegebene URLs abzufangen
Deminetix
Beachten Sie, dass grepcode.com nicht mehr aktiv ist. Ich denke , hier ist ein Link zur richtigen Stelle im Android-Quellcode. Ich denke, der Regex, den Android verwendet, wird möglicherweise seit 2013 aktualisiert (ursprünglicher Beitrag), scheint jedoch seit 2015 nicht mehr aktualisiert worden zu sein und es fehlen möglicherweise einige neuere TLDs.
James
19

Basierend auf der Antwort von Crescent Fresh

Wenn Sie Links mit http: // ODER ohne http: // und über www erkennen möchten . Sie können Folgendes verwenden

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
quelle
Dies ist eine gute Lösung, aber ich möchte auch überprüfen, ob der Text nicht bereits href enthalten sollte. Ich habe diesen regulären Ausdruck versucht = /((?!href)((https?:\/\/)|(www\.)|(mailto:))[^\s‹+)/gi, aber es funktioniert nicht. Können Sie mir dabei helfen oder warum der oben genannte reguläre Ausdruck nicht funktioniert?
Sachin Jagtap
Ich finde es gut, dass Sie der zurückgegebenen Ausgabe auch target = "_ blank" hinzugefügt haben. Diese Version ist was ich wollte. Nichts zu übertrieben (sonst würde ich Linkifyjs verwenden) gerade genug, um die meisten Links zu bekommen.
Michael Kubler
18

Diese Bibliothek auf NPM scheint ziemlich umfassend zu sein: https://www.npmjs.com/package/linkifyjs

Linkify ist ein kleines, aber umfassendes JavaScript-Plugin, mit dem Sie URLs im Klartext finden und in HTML-Links konvertieren können. Es funktioniert mit allen gültigen URLs und E-Mail-Adressen.

Dan Kantor
quelle
4
Ich habe gerade die Implementierung von linkifyjs in meinem Projekt abgeschlossen und es ist fantastisch. Linkifyjs sollte die Antwort auf diese Frage sein. Der andere zu sehen ist github.com/twitter/twitter-text
Uber Schnoz
6

Die Funktion kann weiter verbessert werden, um auch Bilder zu rendern:

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/>'
        }
    }) 
} 

oder für ein Miniaturbild, das auf ein Bild in voller Größe verweist:

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

Und hier ist die Funktion strip (), die die Textzeichenfolge zur Vereinheitlichung vorverarbeitet, indem vorhandenes HTML entfernt wird.

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
quelle
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! ...

Ergebnis:-

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

Es gibt ein vorhandenes npm-Paket: url-regex , installieren Sie es einfach mit yarn add url-regexoder npm install url-regexund verwenden Sie es wie folgt:

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
quelle
0

tmp.innerText ist undefiniert. Sie sollten tmp.innerHTML verwenden

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
quelle
0

Versuche dies:

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);
}

wird auch Urls wie erkennen google.com, http://www.google.bla, http://google.bla, www.google.blaaber nichtgoogle.bla

Kofifus
quelle
0

Sie können einen solchen regulären Ausdruck verwenden, um normale URL-Muster zu extrahieren.

(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,})

Wenn Sie komplexere Muster benötigen, verwenden Sie eine solche Bibliothek.

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

Kang Andrew
quelle
Was ist der Zweck von (?:www\.|(?!www))? Warum sollte wwwww.comungültig sein?
Toto
Du hast recht. Eigentlich habe ich es einfach genommen, da viele den regulären Ausdruck verwenden. Ich würde empfehlen, die oben verlinkte Bibliothek zu verwenden. Wir sollten viele Fälle bei der URL-Erkennung berücksichtigen, daher sollte der reguläre Ausdruck komplizierter sein.
Kang Andrew
0

Generische objektorientierte Lösung

Für Leute wie mich, die Frameworks wie Angular verwenden, mit denen DOM nicht direkt bearbeitet werden kann, habe ich eine Funktion erstellt, die eine Zeichenfolge verwendet und ein Array von url/ plainTextObjekten zurückgibt, mit dem Sie eine beliebige UI-Darstellung erstellen können.

URL-Regex

Für den URL-Abgleich habe ich verwendet (leicht angepasst) h0mayun regulären Ausdruck verwendet:/(?:(?:https?:\/\/)|(?:www\.))[^\s]+/g

Meine Funktion löscht auch Interpunktionszeichen vom Ende einer URL wie .und ,ich glaube, dass dies häufiger eine tatsächliche Interpunktion ist als eine legitime URL-Endung (aber es könnte sein! Dies ist keine strenge Wissenschaft, wie andere Antworten gut erklären). Dafür wende ich das an folgende Regex auf übereinstimmende URLs/^(.+?)([.,?!'"]*)$/ .

Typoskript-Code

    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
quelle
0

Wenn Sie Links mit http: // ODER ohne http: // ODER ftp ODER anderen möglichen Fällen wie dem Entfernen von nachgestellten Satzzeichen am Ende erkennen möchten, sehen Sie sich diesen Code an.

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

Eine einfache Möglichkeit, dies zu verwenden, ist die Verwendung von NPM

npm install --save url-knife
Kang Andrew
quelle