ตรวจสอบ URL ในข้อความด้วย JavaScript


151

ไม่มีใครมีคำแนะนำสำหรับการตรวจสอบ URL ในชุดของสตริงหรือไม่?

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

อัปเดต:ฉันเลิกใช้งาน regex นี้เพื่อตรวจหาลิงก์ ... เห็นได้ชัดว่าหลายปีต่อมา

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

ผู้ช่วยเต็มรูปแบบ (ด้วยการสนับสนุน Handlebars เลือก) คือที่เค้า #


11
อาจไม่ใช่ความคิดที่ดีที่จะลองหาชุด TLD ที่ จำกัด เนื่องจากพวกมันยังคงสร้างชุดใหม่อยู่เรื่อย ๆ
Maxy-B

ตกลง. บางครั้งเราต้องการคือโค้ดที่สามารถอัปเดตได้ด้วย TLD ที่จริงแล้วสามารถสร้างสคริปต์เพื่อผนวก TLD เข้ากับ regex หรือการปรับปรุงรหัสแบบไดนามิก TLDs ในรหัส มีสิ่งต่าง ๆ ในชีวิตที่มีค่าเฉลี่ยเหมือน TLDs และเขตเวลา การควบคุมแบบ จำกัด อาจเป็นการดีที่จะตรวจสอบความถูกต้อง "TLDs" ที่ตรวจสอบได้สำหรับกรณีการใช้ที่อยู่โลกแห่งความจริง
Edward Chan JW

คำตอบ:


217

ก่อนอื่นคุณต้องมี regex ที่เหมาะกับ URL มันยากที่จะทำ ดูที่นี่ , ที่นี่และที่นี่ :

... เกือบทุกอย่างเป็น URL ที่ถูกต้อง มีกฎบางอย่างสำหรับการแบ่งวรรคตอน ไม่มีเครื่องหมายวรรคตอนใด ๆ คุณยังมี URL ที่ถูกต้อง

ตรวจสอบ RFC อย่างระมัดระวังและดูว่าคุณสามารถสร้าง URL "ไม่ถูกต้อง" ได้หรือไม่ กฎมีความยืดหยุ่นมาก

ตัวอย่างเช่น:::::URL ที่ถูกต้อง ":::::"เส้นทางเป็น ชื่อไฟล์ที่สวย แต่เป็นชื่อไฟล์ที่ถูกต้อง

นอกจากนี้ยัง/////เป็น URL ที่ถูกต้อง netloc ( "ชื่อโฮสต์") ""เป็น "///"เส้นทางเป็น อีกครั้งโง่ ใช้ได้อีกด้วย URL นี้เป็นมาตรฐาน"///" ที่เทียบเท่า

สิ่งที่ชอบ"bad://///worse/////" นั้นถูกต้องสมบูรณ์ โง่ แต่ถูกต้อง

อย่างไรก็ตามคำตอบนี้ไม่ได้หมายถึงการให้ regex ที่ดีที่สุดให้กับคุณ แต่เป็นข้อพิสูจน์ถึงวิธีการห่อสตริงภายในข้อความด้วย JavaScript

ตกลงเพื่อให้ใช้เพียงแค่นี้: /(https?:\/\/[^\s]+)/g

อีกครั้งนี้เป็น regex มันจะมีผลบวกผิด ๆ มากมาย อย่างไรก็ตามมันก็ดีพอสำหรับตัวอย่างนี้

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

ดังนั้นโดยรวมลอง:

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

4
ตัวอย่างบางส่วนของ "ผลบวกปลอม" จะช่วยปรับปรุงคำตอบนี้ได้อย่างมาก มิฉะนั้นชาว Google ในอนาคตจะเหลือเพียงบางส่วน (อาจจะถูกต้อง) FUD
cmcculloh

ฉันไม่เคยรู้เลยว่าคุณสามารถผ่านฟังก์ชั่นเป็นพารามิเตอร์ที่สองสำหรับ.replace: |
Aamir Afridi

4
เป็นเรื่องที่ดี แต่มันทำสิ่งที่ "ผิด" ด้วยเครื่องหมายวรรคตอนต่อท้ายtext="Find me at http://www.example.com, and also at http://stackoverflow.com."ในสองยุค 404 ผู้ใช้บางคนทราบเรื่องนี้และจะเพิ่มช่องว่างหลัง URL ก่อนเครื่องหมายวรรคตอนเพื่อหลีกเลี่ยงการแตก แต่ตัวเชื่อมโยงส่วนใหญ่ที่ฉันใช้ (Gmail, etherpad, phabricator) จะแยกเครื่องหมายวรรคตอนต่อท้ายออกจาก URL
skierpage

ในกรณีที่ข้อความมี URL ที่ยึดแล้วคุณสามารถใช้ฟังก์ชั่น removeAnchors (ข้อความ) {var div = $ ('<div> </div>') .html (ข้อความ); div.find ( 'a') เนื้อหา () แกะ ()..; ส่งคืน div.text (); } เพื่อเอาจุดยึดออกก่อนที่จะส่งคืนข้อความแทนที่
Muneeb Mirza

หากข้อความมี URL ที่ยึดอยู่แล้วคุณกำลังใช้ jQuery เพื่อลบจุดยึด แต่ฉันใช้ Angular ฉันจะเอาสมอออกใน Angular ได้อย่างไร
Sachin Jagtap

132

นี่คือสิ่งที่ฉันลงเอยด้วยการใช้เป็น regex ของฉัน:

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

สิ่งนี้ไม่รวมเครื่องหมายวรรคตอนต่อท้ายใน URL ฟังก์ชั่นของวงเดือนทำงานเหมือนมีเสน่ห์ :) ดังนั้น:

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
ในที่สุด regex ที่ใช้งานได้จริงในกรณีที่ชัดเจนที่สุด! อันนี้สมควรได้รับการคั่นหน้า ฉันทดสอบตัวอย่างมากมายจากการค้นหาของ Google จนกว่าฉันจะพบสิ่งนี้
Ismael

6
เรียบง่ายและดี! แต่สิ่งที่urlRegexควรนิยามไว้ภายนอก linkifyคือการรวบรวมมันมีราคาแพง
BM

1
สิ่งนี้ล้มเหลวในการตรวจหา URL เต็ม: disney.wikia.com/wiki/Pua_(Moana)
Jry9972

1
ฉันเพิ่ม()ในแต่ละรายการของตัวละครและตอนนี้ทำงาน
Guillaume F.

3
มันตรวจไม่พบ url ที่ขึ้นต้นด้วย www เพียงอย่างเดียว ตัวอย่างเช่น: www.facebook.com
CraZyDroiD

51

ฉันใช้ปัญหานี้ไปซักพักแล้วก็เกิดขึ้นกับฉันว่ามีวิธีการ Android, android.text.util.Linkify ซึ่งใช้ regexes ที่แข็งแกร่งพอที่จะทำสิ่งนี้ได้ โชคดีที่ Android เป็นโอเพ่นซอร์ส

พวกเขาใช้รูปแบบที่แตกต่างกันเล็กน้อยเพื่อจับคู่ URL ประเภทต่างๆ คุณสามารถค้นหาได้ที่นี่: 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

หากคุณกังวลเกี่ยวกับ URL ที่ตรงกับ WEB_URL_PATTERN นั่นคือ URL ที่สอดคล้องกับข้อกำหนด RFC 1738 คุณสามารถใช้สิ่งนี้:

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

นี่คือข้อความเต็มของแหล่งที่มา:

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

หากคุณต้องการแฟนซีคุณสามารถทดสอบที่อยู่อีเมลได้เช่นกัน regex สำหรับที่อยู่อีเมลคือ:

/[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: โดเมนระดับบนสุดที่รองรับโดย regex ข้างต้นเป็นปัจจุบัน ณ เดือนมิถุนายน 2550 สำหรับรายการล่าสุดคุณจะต้องตรวจสอบhttps://data.iana.org/TLD/tlds-alpha-by-domain.txt .


3
ตั้งแต่คุณมีกรณีตายแสดงออกปกติคุณไม่ได้มีการระบุและa-zA-Z http|https|Http|Https|rtsp|Rtsp
Ry-

4
นี่เป็นสิ่งที่ดี แต่ฉันไม่แน่ใจว่าฉันจะใช้มัน สำหรับกรณีการใช้งานส่วนใหญ่ฉันควรยอมรับผลบวกปลอม ๆ มากกว่าใช้วิธีการที่ใช้รายการ TLD ที่กำหนดค่าตายตัว หากคุณแสดงรายการ TLD ในรหัสของคุณคุณรับประกันได้ว่าจะล้าสมัยในหนึ่งวันและฉันไม่ต้องการสร้างการบำรุงรักษาที่จำเป็นในอนาคตในรหัสของฉันหากฉันสามารถหลีกเลี่ยงได้
Mark Amery

3
วิธีนี้ใช้งานได้ 101% แต่น่าเสียดายที่มันพบ URL ที่ไม่ได้นำหน้าด้วยช่องว่าง หากฉันทำการแข่งขันบน hello@mydomain.com จะจับ 'mydomain.com' มีวิธีที่จะปรับปรุงให้ดีขึ้นหรือไม่หากมีพื้นที่ก่อนหน้า?
Deminetix

นอกจากนี้ยังควรทราบนี่เป็นสิ่งที่สมบูรณ์แบบสำหรับการจับ URL ที่ป้อนโดยผู้ใช้
Deminetix

โปรดทราบว่า grepcode.com ไม่มีอีกต่อไปนี่คือสิ่งที่ฉันคิดว่าเป็นลิงก์ไปยังที่ที่ถูกต้องในซอร์สโค้ด Android ฉันคิดว่า regex Android กำลังใช้งานอาจได้รับการอัปเดตตั้งแต่ปี 2013 (โพสต์ดั้งเดิม) แต่ดูเหมือนจะไม่ได้รับการอัปเดตตั้งแต่ปี 2015 และอาจขาด TLD รุ่นใหม่บางตัว
James

19

ขึ้นอยู่กับคำตอบของวงเดือนสด

หากคุณต้องการตรวจจับลิงก์ด้วย http: //หรือไม่มี http: // และโดย www คุณสามารถใช้สิ่งต่อไปนี้

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

นี่เป็นทางออกที่ดี แต่ฉันต้องการตรวจสอบว่าข้อความไม่ควรมี href อยู่ในนั้น ฉันลองใช้ regex นี้ = /((?!href)((https?:?/??????????????????????????????????????????????????????????????????????????????????????????????????????????) แต่? คุณสามารถช่วยฉันด้วยหรือทำไม regex ข้างต้นไม่ทำงาน
Sachin Jagtap

ฉันชอบที่คุณได้เพิ่ม target = "_ blank" ไปยังผลลัพธ์ที่ส่งคืน รุ่นนี้เป็นสิ่งที่ฉันต้องการ ไม่มีสิ่งใดอยู่ด้านบน (อย่างอื่นฉันจะใช้ Linkifyjs) พอที่จะรับลิงก์ส่วนใหญ่
Michael Kubler

18

ไลบรารีบน NPM นี้ดูเหมือนว่าจะครอบคลุมอย่างสมบูรณ์https://www.npmjs.com/package/linkifyjs

Linkify เป็นปลั๊กอิน JavaScript ขนาดเล็ก แต่ครอบคลุมสำหรับการค้นหา URL ในข้อความธรรมดาและแปลงเป็นลิงก์ HTML ใช้งานได้กับ URL และที่อยู่อีเมลที่ถูกต้องทั้งหมด


4
ฉันเพิ่งจะใช้งาน linkifyjs ในโครงการของฉันและมันยอดเยี่ยมมาก Linkifyjs ควรเป็นคำตอบสำหรับคำถามนี้ อีกอันคือgithub.com/twitter/twitter-text
Uber Schnoz

6

สามารถปรับปรุงฟังก์ชั่นเพิ่มเติมเพื่อแสดงภาพได้เช่นกัน:

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

หรือสำหรับภาพขนาดย่อที่เชื่อมโยงไปยังภาพขนาดเต็ม:

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

และนี่คือฟังก์ชั่นแถบ () ที่ประมวลผลล่วงหน้าสตริงข้อความเพื่อความสม่ำเสมอโดยการลบ 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>")

รหัสย่องานใหญ่! ...

ผลลัพธ์:-

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

1

มีแพ็กเกจ npm ที่มีอยู่: url-regexเพียงติดตั้งด้วยyarn add url-regexหรือnpm install url-regexและใช้ดังต่อไปนี้:

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 ไม่ได้กำหนด คุณควรใช้ 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

ลองนี้:

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

นอกจากนี้ยังจะรับรู้ URL ที่เช่น google.com, http://www.google.bla, http://google.bla, www.google.blaแต่ไม่google.bla


0

คุณสามารถใช้ regex เช่นนี้เพื่อแยกรูปแบบ 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,})

หากคุณต้องการรูปแบบที่ซับซ้อนยิ่งขึ้นให้ใช้ห้องสมุดเช่นนี้

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


มีจุดประสงค์(?:www\.|(?!www))อะไร? ทำไมwwwww.comต้องไม่ถูกต้อง?
โตโต้

คุณพูดถูก ที่จริงฉันเพิ่งเอามาใช้มากเท่าที่ใช้ regex ฉันขอแนะนำให้ใช้ห้องสมุดที่ลิงก์ด้านบน เราควรพิจารณาหลาย ๆ กรณีในการตรวจจับ url ดังนั้น regex ควรมีความซับซ้อนมากขึ้น
Kang Andrew

0

โซลูชันเชิงวัตถุทั่วไป

สำหรับคนอย่างฉันที่ใช้เฟรมเวิร์กเช่นเชิงมุมที่ไม่อนุญาตให้จัดการ DOM โดยตรงฉันสร้างฟังก์ชันที่รับสตริงและส่งกลับอาร์เรย์ของurl/ plainTextวัตถุที่สามารถใช้เพื่อสร้างการแสดง UI ที่คุณต้องการ

URL regex

สำหรับการจับคู่ URL ที่ฉันใช้ (ดัดแปลงเล็กน้อย) h0mayunregex:/(?:(?:https?:\/\/)|(?:www\.))[^\s]+/g

ฟังก์ชั่นของฉันลดลงเครื่องหมายวรรคตอนจากท้าย URL เช่นกัน.และ,ฉันเชื่อว่าบ่อยครั้งจะเป็นเครื่องหมายวรรคตอนที่แท้จริงมากกว่าการสิ้นสุด URL ที่ถูกต้อง (แต่อาจเป็นได้! นี่ไม่ใช่วิทยาศาสตร์ที่เข้มงวดตามคำตอบอื่น ๆ ) ต่อไปนี้ regex ไปยัง /^(.+?)([.,?!'"]*)$/URL ที่จับคู่

รหัส typescript

    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

หากคุณต้องการตรวจสอบลิงก์ด้วย http: // หรือไม่มี http: // หรือ ftp หรือกรณีอื่น ๆ ที่เป็นไปได้เช่นการลบเครื่องหมายวรรคตอนท้ายที่ท้ายให้ดูที่รหัสนี้

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

วิธีง่ายๆในการใช้นั่นคือใช้ NPM

npm install --save url-knife
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.