Wykrywaj adresy URL w tekście za pomocą JavaScript


151

Czy ktoś ma sugestie dotyczące wykrywania adresów URL w zestawie ciągów?

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

Aktualizacja: Skończyło się na używaniu tego wyrażenia regularnego do wykrywania linków… Najwyraźniej kilka lat później.

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

Pełen pomocnik (z opcjonalnym wsparciem dla kierownicy ) znajduje się pod numerem 1654670 .


11
Prawdopodobnie nie jest dobrym pomysłem wymienienie skończonego zestawu domen najwyższego poziomu, ponieważ wciąż tworzą nowe.
Maxy-B

Zgodzić się. Czasami potrzebujemy kodu z możliwością aktualizacji za pomocą TLD. Właściwie można zbudować skrypt, aby dołączyć TLD do wyrażenia regularnego lub dynamicznie aktualizować TLD w kodzie. Są rzeczy w życiu, które trzeba ujednolicić, takie jak TLD i strefa czasowa. Kontrola skończona może być dobra do zweryfikowania istniejących „TLD” możliwych do zweryfikowania adresów URL w przypadku użycia adresu w świecie rzeczywistym.
Edward Chan JW

Odpowiedzi:


217

Najpierw potrzebujesz dobrego wyrażenia regularnego, które pasuje do adresów URL. To jest trudne. Zobacz tutaj , tutaj i tutaj :

... prawie wszystko jest prawidłowym adresem URL. Istnieją pewne zasady interpunkcyjne dotyczące dzielenia go. Brak interpunkcji oznacza, że ​​nadal masz prawidłowy adres URL.

Sprawdź dokładnie RFC i zobacz, czy możesz skonstruować „nieprawidłowy” adres URL. Zasady są bardzo elastyczne.

Na przykład :::::to prawidłowy adres URL. Ścieżka jest ":::::". Dość głupia nazwa pliku, ale poprawna nazwa pliku.

Ponadto, /////jest to prawidłowy adres URL. Netloc („nazwa hosta”) to "". Ścieżka jest "///". Znowu głupia. Również ważne. Ten adres URL normalizuje się, "///" który jest odpowiednikiem.

Coś takiego "bad://///worse/////" jest całkowicie poprawne. Głupi, ale ważny.

W każdym razie ta odpowiedź nie ma na celu dostarczenia najlepszego wyrażenia regularnego, ale raczej dowód na to, jak wykonać zawijanie łańcucha wewnątrz tekstu za pomocą JavaScript.

OK, więc użyjmy tego: /(https?:\/\/[^\s]+)/g

Ponownie, jest to zły regex . Będzie miał wiele fałszywych alarmów. Jednak jest wystarczająco dobry dla tego przykładu.

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

Podsumowując, spróbuj:

$$('#pad dl dd').each(function(element) {
    element.innerHTML = urlify(element.innerHTML);
});

4
Niektóre przykłady „wielu fałszywych alarmów” znacznie poprawiłyby tę odpowiedź. W przeciwnym razie przyszli Googlersi zostaną po prostu z niektórymi (może ważnymi?) FUD.
cmcculloh

Nigdy nie wiedziałem, że możesz przekazać funkcję jako drugi parametr dla .replace: |
Aamir Afridi

4
To dobrze, ale robi „źle”, a końcowe znaki interpunkcyjne text="Find me at http://www.example.com, and also at http://stackoverflow.com."skutkują dwoma 404. Niektórzy użytkownicy są tego świadomi i dodają spację po adresach URL przed interpunkcją, aby uniknąć zerwania, ale większość linkówfiers, z których korzystam (Gmail, etherpad, phabricator), oddziela końcowe znaki interpunkcyjne od adresu URL.
narciarz 30.07.15

W przypadku, gdy tekst zawiera już zakotwiczony adres URL, możesz użyć funkcji removeAnchors (text) {var div = $ ('<div> </div>') .html (text); div.find ('a'). zawartość (). unrap (); return div.text (); } aby najpierw usunąć kotwice przed powrotem text.replace
Muneeb Mirza

Jeśli tekst zawiera już zakotwiczony adres URL, używasz jquery do usuwania kotwicy, ale ja używam Angular. Jak mogę usunąć kotwicę w Angular?
Sachin Jagtap

132

Oto, czego ostatecznie użyłem jako mojego wyrażenia regularnego:

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

Nie obejmuje to końcowych znaków interpunkcyjnych w adresie URL. Funkcja Crescent działa jak urok :) więc:

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

4
Wreszcie regex, który naprawdę działa w najbardziej oczywistym przypadku! Ten zasługuje na zakładkę. Przetestowałem tysiące przykładów z wyszukiwarki Google, dopóki tego nie znalazłem.
Ismael

6
Proste i przyjemne! Ale urlRegexpowinno być zdefiniowane na zewnątrz, linkify ponieważ kompilacja jest kosztowna.
BM

1
To nie pozwala wykryć pełnego adresu URL: disney.wikia.com/wiki/Pua_(Moana)
Jry9972

1
Dodałem ()w każdej liście znaków i teraz działa.
Guillaume F.

3
nie wykrywa adresu URL zaczynającego się od samego www. np. www.facebook.com
CraZyDroiD

51

Szukałem w Google ten problem przez dłuższy czas, a potem przyszło mi do głowy, że istnieje metoda Android.text.util.Linkify, która wykorzystuje do tego dość solidne wyrażenia regularne. Na szczęście Android jest open source.

Używają kilku różnych wzorców dopasowywania różnych typów adresów URL. Znajdziesz je wszystkie tutaj: 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

Jeśli martwisz się tylko adresami URL zgodnymi z WEB_URL_PATTERN, czyli adresami URL zgodnymi ze specyfikacją RFC 1738, możesz użyć tego:

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

Oto pełny tekst źródła:

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

Jeśli chcesz być naprawdę fantazyjny, możesz również przetestować adresy e-mail. Wyrażenie regularne dla adresów e-mail to:

/[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: domeny najwyższego poziomu obsługiwane przez powyższe wyrażenie regularne są aktualne w czerwcu 2007 r. Aby uzyskać aktualną listę, sprawdź https://data.iana.org/TLD/tlds-alpha-by-domain.txt .


3
Ponieważ masz wyrażenie regularne bez rozróżniania wielkości liter, nie musisz określać a-zA-Zi http|https|Http|Https|rtsp|Rtsp.
Ry-

4
To miłe, ale nie jestem pewien, czy kiedykolwiek z niego skorzystam. W większości przypadków wolę zaakceptować fałszywe alarmy niż zastosować podejście, które opiera się na zakodowanej liście TLD. Jeśli umieścisz domeny TLD w swoim kodzie, gwarantujesz, że pewnego dnia będzie on przestarzały i wolałbym nie budować obowiązkowej przyszłej konserwacji w moim kodzie, jeśli mogę tego uniknąć.
Mark Amery,

3
Działa to w 101% przypadków, niestety znajduje również adresy URL, które nie są poprzedzone spacją. Jeśli uruchomię dopasowanie na hello@mydomain.com, przechwytuje „mydomain.com”. Czy jest sposób, aby to poprawić, aby złapać go tylko wtedy, gdy ma przed nim spację?
Deminetix

Warto również zauważyć, że jest to idealne rozwiązanie do przechwytywania adresów URL wprowadzonych przez użytkowników
Deminetix

Zauważ, że grepcode.com już nie działa, oto, co moim zdaniem, jest linkiem do właściwego miejsca w kodzie źródłowym Androida. Myślę, że wyrażenie regularne używane przez Androida może zostać zaktualizowane od 2013 r. (Oryginalny post), ale nie wydaje się, aby zostało zaktualizowane od 2015 r., A zatem może brakować niektórych nowszych domen TLD.
James

19

Na podstawie odpowiedzi Crescent Fresh

jeśli chcesz wykryć linki z http: // LUB bez http: // i przez www. możesz użyć następujących

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

To dobre rozwiązanie, ale chcę też sprawdzić, czy tekst nie powinien już zawierać href. Wypróbowałem to wyrażenie regularne = /((?!href)((https?:\/\/)|(www\.)|(mailto:)))[^\s]+)/gi, ale nie działa. Czy możesz mi z tym pomóc lub dlaczego powyższe wyrażenie regularne nie działa.
Sachin Jagtap

Podoba mi się, że do zwróconego wyniku dodałeś również target = "_ blank". Ta wersja jest tym, czego chciałem. Nic przesadnego (w przeciwnym razie użyłbym Linkifyjs) tylko tyle, aby uzyskać większość linków.
Michael Kubler

18

Ta biblioteka NPM wygląda na dość obszerną https://www.npmjs.com/package/linkifyjs

Linkify to mała, ale wszechstronna wtyczka JavaScript do znajdowania adresów URL w postaci zwykłego tekstu i konwertowania ich na linki HTML. Działa ze wszystkimi prawidłowymi adresami URL i adresami e-mail.


4
Właśnie skończyłem wdrażać linkifyjs w moim projekcie i jest fantastycznie. Linkifyjs powinno być odpowiedzią na to pytanie. Drugi, na który warto zwrócić uwagę, to github.com/twitter/twitter-text
Uber Schnoz

6

Funkcję można dodatkowo ulepszyć, aby renderować również obrazy:

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

lub w przypadku miniatury zawierającej link do obrazu o pełnym rozmiarze:

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

A oto funkcja strip (), która wstępnie przetwarza ciąg tekstowy w celu zapewnienia jednolitości, usuwając istniejący kod HTML.

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

2
let str = 'https://example.com is a great site'
str.replace(/(https?:\/\/[^\s]+)/g,"<a href='$1' target='_blank' >$1</a>")

Krótki kod Wielka praca! ...

Wynik:-

 <a href="https://example.com" target="_blank" > https://example.com </a>

1

Istnieje pakiet npm: url-regex , po prostu zainstaluj go z yarn add url-regexlub npm install url-regexi użyj w następujący sposób:

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

0

tmp.innerText jest niezdefiniowana. Powinieneś użyć 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 
    })

0

Spróbuj tego:

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

rozpozna także adresy URL, takich jak google.com, http://www.google.bla, http://google.bla, www.google.blaale niegoogle.bla


0

Możesz użyć takiego wyrażenia regularnego, aby wyodrębnić normalne wzorce adresów URL.

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

Jeśli potrzebujesz bardziej wyszukanych wzorów, skorzystaj z takiej biblioteki.

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


Jaki jest cel (?:www\.|(?!www))? Dlaczego powinien wwwww.combyć nieważny?
Toto,

Masz rację. Właściwie wziąłem to tak, jak wielu używa wyrażenia regularnego. Polecam skorzystać z połączonej biblioteki powyżej. Powinniśmy wziąć pod uwagę wiele przypadków w wykrywaniu adresów URL, więc wyrażenie regularne powinno być bardziej skomplikowane.
Kang Andrew,

0

Ogólne rozwiązanie zorientowane obiektowo

Dla ludzi takich jak ja, którzy używają frameworków takich jak angular, które nie pozwalają na bezpośrednie manipulowanie DOM, stworzyłem funkcję, która pobiera ciąg znaków i zwraca tablicę obiektów url/ plainText, których można użyć do stworzenia dowolnej reprezentacji interfejsu użytkownika.

URL wyrażenia regularnego

Do dopasowania adresu URL użyłem (nieznacznie dostosowanego) h0mayunwyrażenia regularnego:/(?:(?:https?:\/\/)|(?:www\.))[^\s]+/g

Moja funkcja usuwa również znaki interpunkcyjne z końca adresu URL, takiego jak .i ,uważam, że częściej będzie to rzeczywista interpunkcja niż prawidłowe zakończenie adresu URL (ale może być! To nie jest rygorystyczna nauka, jak dobrze wyjaśniają inne odpowiedzi) W tym celu stosuję następujące wyrażenie regularne w dopasowanych adresach URL /^(.+?)([.,?!'"]*)$/.

Kod maszynopisu

    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
    }

0

Jeśli chcesz wykryć linki z http: // LUB bez http: // LUB ftp LUB w innych możliwych przypadkach, takich jak usunięcie końcowej interpunkcji na końcu, spójrz na ten kod.

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

Prostym sposobem na to jest użycie NPM

npm install --save url-knife
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.