Deteksi URL dalam teks dengan JavaScript

151

Adakah yang punya saran untuk mendeteksi URL dalam serangkaian string?

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

Pembaruan: Saya akhirnya menggunakan regex ini untuk deteksi tautan ... Rupanya beberapa tahun kemudian.

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

Pembantu penuh (dengan dukungan Setang opsional) ada di inti # 1654670 .

arbales
sumber
11
Mungkin bukan ide yang baik untuk mencoba membuat daftar TLD yang terbatas, karena mereka terus membuat yang baru.
Maxy-B
Setuju. Terkadang yang kita butuhkan adalah kode yang dapat diperbarui dengan TLD. Sebenarnya dapat dibangun skrip untuk menambahkan TLD ke dalam regex atau pembaruan kode dinamis TLD dalam kode. Ada hal-hal dalam hidup yang harus distandarisasi seperti TLD dan Timezone. Kontrol terbatas mungkin baik untuk memverifikasi URL yang dapat diverifikasi "TLD" untuk kasus penggunaan alamat Real World.
Edward Chan JW

Jawaban:

217

Pertama, Anda membutuhkan regex yang cocok dengan url. Ini sulit dilakukan. Lihat di sini , di sini dan di sini :

... hampir semuanya adalah URL yang valid. Ada beberapa aturan tanda baca untuk memisahkannya. Tanpa tanda baca apa pun, Anda masih memiliki URL yang valid.

Periksa RFC dengan cermat dan lihat apakah Anda dapat membuat URL "tidak valid". Aturannya sangat fleksibel.

Misalnya :::::adalah URL yang valid. Jalannya adalah ":::::". Nama file yang sangat bodoh, tetapi nama file yang valid.

Juga, /////URL yang valid. Netloc ("hostname") adalah "". Jalannya adalah "///". Sekali lagi, bodoh. Juga valid. URL ini dinormalisasi dengan "///" yang setara.

Sesuatu seperti "bad://///worse/////" itu sangat valid. Bodoh tapi valid.

Lagi pula, jawaban ini tidak dimaksudkan untuk memberi Anda regex terbaik tetapi lebih sebagai bukti bagaimana melakukan pembungkus string di dalam teks, dengan JavaScript.

OK jadi mari kita gunakan yang satu ini: /(https?:\/\/[^\s]+)/g

Sekali lagi, ini adalah regex yang buruk . Ini akan memiliki banyak kesalahan positif. Namun itu cukup baik untuk contoh ini.

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

Singkatnya, cobalah:

$$('#pad dl dd').each(function(element) {
    element.innerHTML = urlify(element.innerHTML);
});
Crescent Fresh
sumber
4
Beberapa contoh "banyak kesalahan positif" akan sangat meningkatkan jawaban ini. Kalau tidak, Googler masa depan hanya dibiarkan dengan beberapa FUD (mungkin valid?).
cmcculloh
Saya tidak pernah tahu Anda dapat melewati fungsi sebagai param kedua untuk .replace: |
Aamir Afridi
4
Itu bagus, tetapi ia melakukan hal yang "salah" dengan tanda baca tertinggal text="Find me at http://www.example.com, and also at http://stackoverflow.com."dalam dua 404-an. Beberapa pengguna mengetahui hal ini dan akan menambahkan spasi setelah URL sebelum tanda baca untuk menghindari kerusakan, tetapi sebagian besar pengenal tautan yang saya gunakan (Gmail, etherpad, phabricator) memisahkan tanda baca jejak dari URL.
skierpage
Dalam hal teks sudah berisi url berlabuh Anda dapat menggunakan fungsi removeAnchors (teks) {var div = $ ('<div> </div>') .html (teks); div.find ('a'). content (). unwrap (); return div.text (); } untuk menghapus jangkar terlebih dahulu sebelum mengembalikan text.replace
Muneeb Mirza
Jika teks sudah berisi url berlabuh, Anda menggunakan jquery untuk menghapus jangkar, tetapi saya menggunakan Angular. Bagaimana saya bisa menghapus jangkar di Angular?
Sachin Jagtap
132

Inilah yang akhirnya saya gunakan sebagai regex saya:

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

Ini tidak termasuk tanda baca di URL. Fungsi Crescent bekerja seperti pesona :) jadi:

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
sumber
4
Akhirnya sebuah regex yang benar-benar berfungsi dalam kasus yang paling jelas! Yang ini layak bookmark. Saya menguji ribuan contoh dari pencarian Google hingga saya menemukan ini.
Ismael
6
Sederhana dan menyenangkan! Tetapi urlRegexharus didefinisikan di luar linkify sebagai kompilasi itu mahal.
BM
1
Ini gagal mendeteksi URL lengkap: disney.wikia.com/wiki/Pua_(Moana)
Jry9972
1
Saya menambahkan ()di setiap daftar karakter dan berfungsi sekarang.
Guillaume F.
3
gagal mendeteksi url yang dimulai hanya dengan www. misalnya: www.facebook.com
CraZyDroiD
51

Saya mencari-cari masalah ini untuk beberapa saat, kemudian terpikir oleh saya bahwa ada metode Android, android.text.util.Linkify, yang menggunakan beberapa regex yang cukup kuat untuk mencapai hal ini. Untungnya, Android adalah open source.

Mereka menggunakan beberapa pola berbeda untuk mencocokkan berbagai jenis url. Anda dapat menemukannya di sini: 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

Jika Anda hanya khawatir tentang url yang cocok dengan WEB_URL_PATTERN, yaitu, url yang sesuai dengan spesifikasi RFC 1738, Anda dapat menggunakan ini:

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

Berikut ini teks lengkap sumbernya:

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

Jika Anda ingin benar-benar mewah, Anda dapat menguji alamat email juga. Regex untuk alamat email adalah:

/[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: Domain tingkat atas yang didukung oleh regex di atas adalah terbaru pada Juni 2007. Untuk daftar yang terbaru Anda perlu memeriksa https://data.iana.org/TLD/tlds-alpha-by-domain.txt .

Adam
sumber
3
Karena Anda memiliki ekspresi reguler yang tidak peka huruf besar-kecil, Anda tidak perlu menentukan a-zA-Zdan http|https|Http|Https|rtsp|Rtsp.
Ry-
4
Ini bagus, tapi saya tidak yakin pernah menggunakannya. Untuk sebagian besar kasus penggunaan, saya lebih suka menerima beberapa positif palsu daripada menggunakan pendekatan yang bergantung pada daftar TLD yang dikodekan dengan keras. Jika Anda mendaftar TLD dalam kode Anda, Anda menjamin bahwa itu akan menjadi usang suatu hari, dan saya lebih suka tidak membangun pemeliharaan wajib di masa depan ke dalam kode saya jika saya bisa menghindarinya.
Mark Amery
3
Ini berfungsi 101% dari waktu, sayangnya itu juga menemukan url yang tidak didahului oleh spasi. Jika saya menjalankan kecocokan di [email protected] itu menangkap 'mydomain.com'. Apakah ada cara untuk memperbaiki ini hanya dengan menangkapnya jika memiliki ruang sebelumnya?
Deminetix
Perlu diketahui juga, ini sangat cocok untuk menangkap url yang dimasukkan pengguna
Deminetix
Perhatikan bahwa grepcode.com tidak lagi berfungsi, inilah yang menurut saya merupakan tautan ke tempat yang tepat dalam kode sumber Android. Saya pikir regex yang digunakan Android mungkin diperbarui sejak 2013 (pos asli), tetapi tampaknya tidak diperbarui sejak 2015 dan karenanya mungkin hilang beberapa TLD yang lebih baru.
James
19

Berdasarkan jawaban Crescent Fresh

jika Anda ingin mendeteksi tautan dengan http: // ATAU tanpa http: // dan oleh www. Anda dapat menggunakan yang berikut ini

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
sumber
Ini adalah solusi yang baik, tetapi saya juga ingin memeriksa teks yang seharusnya tidak memiliki href di dalamnya. Saya mencoba regex ini = /((?!href)((https?:\/\/)|(www#.)|(mailto:##########) tetapi tidak berfungsi. Bisakah Anda membantu saya atau mengapa regex di atas tidak berfungsi?
Sachin Jagtap
Saya suka bahwa Anda juga menambahkan target = "_ blank" ke output yang dikembalikan. Versi ini yang saya inginkan. Tidak ada yang terlalu di atas (kalau tidak saya akan menggunakan Linkifyjs) hanya cukup untuk mendapatkan sebagian besar tautan.
Michael Kubler
18

Pustaka ini di NPM sepertinya cukup komprehensif https://www.npmjs.com/package/linkifyjs

Linkify adalah plugin JavaScript kecil namun komprehensif untuk menemukan URL dalam teks biasa dan mengubahnya menjadi tautan HTML. Ini berfungsi dengan semua URL dan alamat email yang valid.

Dan Kantor
sumber
4
Saya baru saja selesai mengimplementasikan tautan-tautan dalam proyek saya dan ini sangat fantastis. Linkifyjs harus menjadi jawaban untuk pertanyaan ini. Yang lain untuk dilihat adalah github.com/twitter/twitter-text
Uber Schnoz
6

Fungsi dapat lebih ditingkatkan untuk membuat gambar juga:

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

atau untuk gambar mini yang menghubungkan ke gambar ukuran penuh:

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

Dan di sini adalah fungsi strip () yang pra-proses string teks untuk keseragaman dengan menghapus html yang ada.

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

Kode Pendek Kerja Besar! ...

Hasil:-

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

Ada paket npm yang ada: url-regex , cukup instal dengan yarn add url-regexatau npm install url-regexdan gunakan sebagai berikut:

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

tmp.innerText tidak ditentukan. Anda harus menggunakan 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
sumber
0

coba ini:

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

juga akan mengenali url seperti google.com, http://www.google.bla, http://google.bla, www.google.blatapi tidakgoogle.bla

kofifus
sumber
0

Anda dapat menggunakan regex seperti ini untuk mengekstrak pola url normal.

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

Jika Anda membutuhkan pola yang lebih canggih, gunakan perpustakaan seperti ini.

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

Kang Andrew
sumber
Apa tujuannya (?:www\.|(?!www))? Mengapa wwwww.comtidak valid?
Toto
Kamu benar. Sebenarnya saya hanya mengambilnya sebanyak-banyaknya menggunakan regex. Saya akan merekomendasikan menggunakan pustaka tertaut di atas. Kami harus mempertimbangkan banyak kasus dalam deteksi url, sehingga regex harus lebih rumit.
Kang Andrew
0

Solusi Berorientasi Objek Umum

Untuk orang-orang seperti saya yang menggunakan kerangka kerja seperti sudut yang tidak memungkinkan memanipulasi DOM secara langsung, saya membuat fungsi yang mengambil string dan mengembalikan array url/ plainTextobjek yang dapat digunakan untuk membuat representasi UI yang Anda inginkan.

Regex URL

Untuk pencocokan URL saya menggunakan h0mayunregex (sedikit disesuaikan) :/(?:(?:https?:\/\/)|(?:www\.))[^\s]+/g

Fungsi saya juga menjatuhkan karakter tanda baca dari akhir URL seperti .dan ,yang saya percaya lebih sering akan menjadi tanda baca yang sebenarnya daripada akhiran URL yang sah (tetapi bisa saja! Ini bukan ilmu yang keras seperti yang dijelaskan oleh jawaban lain dengan baik) Untuk itu saya menerapkan mengikuti regex ke URL yang cocok /^(.+?)([.,?!'"]*)$/.

Kode skrip

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

Jika Anda ingin mendeteksi tautan dengan http: // ATAU tanpa http: // ATAU ftp ATAU kasus lain yang mungkin seperti menghapus tanda baca tertinggal di bagian akhir, lihat kode ini.

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

Cara sederhana untuk menggunakannya adalah menggunakan NPM

npm install --save url-knife
Kang Andrew
sumber