匹配一段文本中URL的正則問題

在項目中有個這樣的設計,備註中的URL自動識別為點擊的鏈接,對此的處理方式是用正則匹配出URL部分,然後替換成<a href=URL>URL這樣即可。其主要部分是正則匹配出URL部分。

假設有這麼一段文本。

你好,我是一段文本。我鏈接到http://leeiio.me/test.html請大家多多指教。

那麼我們可以這麼寫。

var text = "你好,我是一段文本。我鏈接到http://leeiio.me/test.html請大家多多指教。";
var regexp = /((http|ftp|https|file):\/\/([\w\-]+\.)+[\w\-]+(\/[\w\-\.\/?\@\%\!\&=\+\~\:\#\;\,]*)?)/ig;
text = text.replace(regexp,"<a href='$1'>$1</a>");
console.log(text);

但是如果URL中帶有中文,那麼以上的就不頂事了。

雖然我們不應該用中文作為URL的一部分,已經把中文部分encode掉,但是很多人比如粗心的寫wordpressd的人,通常不指定Slug,那麼很多URL自然也就帶上了標題的中文了。比如:

假設有這麼一段文本。

你好,我是一段文本。我鏈接到http://leeiio.me/這是一篇測試.html 請大家多多指教。

那麼應該把正則改成這樣

var text = "你好,我是一段文本。我鏈接到http://leeiio.me/這是一篇測試.html 請大家多多指教。";
var regexp = /((http|ftp|https|file):\/\/([\w\-]+\.)+[\w\-]+(\/[\w\u4e00-\u9fa5\-\.\/?\@\%\!\&=\+\~\:\#\;\,]*)?)/ig;
text = text.replace(regexp,"<a href='$1'>$1</a>");
console.log(text);

不過如果以上這段文本在”html”和”請”字中間沒有空格的話,也會錯誤地把後面的”請大家多多指教。”識別為URL的一部分,所以說也並不是十分完美。而且如果標題是漢文呢?日文呢?就不行了,因為剛才正則中增加的\u4e00-\u9fa5隻是中文的編碼區間。

既然如此我們就使用更加暴力的正則吧。比如這麼一段文本:

你好,我是一段文本。我鏈接到http://leeiio.me/這是一篇測試.html 請大家多多指教。
こんにちは、私はテキストをしています。私はこれはテストですhttp://leeiio.me/にリンクしています.Html のは、展覧會をしてください。
안녕, 난 텍스트입니다. 나는 이것은 테스트입니다 http://leeiio.me/에연결할수있습니다.HTML 을 전시주세요.

對應的正則匹配換成這種

var text = "你好,我是一段文本。我鏈接到http://leeiio.me/這是一篇測試.html 請大家多多指教。こんにちは、私はテキストをしています。私はこれはテストですhttp://leeiio.me/にリンクしています.Html のは、展覧會をしてください。안녕, 난 텍스트입니다. 나는 이것은 테스트입니다 http://leeiio.me/에연결할수있습니다.HTML 을 전시주세요.";
var regexp = /((http|ftp|https|file):[^'"\s]+)/ig;
text = text.replace(regexp,"<a href='$1'>$1</a>");
console.log(text);

最終的匹配結果是:

你好,我是一段文本。我鏈 接到<a href=’http://leeiio.me/這是一篇測試.html’>http://leeiio.me/這是一篇測試.html< /a> 請大家多多指教。こんにちは、私はテキストをしています。私はこれはテストです<a href=’http://leeiio.me/にリンクしています.Html’>http://leeiio.me/にリンクしていま す.Html のは、展覧會をしてください。안녕, 난 텍스트입니다. 나는 이것은 테스트입니다 <a href=’http://leeiio.me/에연결할수있습니다.HTML’>http://leeiio.me/에연결할수있습니 다.HTML 을 전시주세요.

當然同上,網址和文字之間得用空格隔開,不然還是會把後面的文字部分也識別為URL的一部分。對於英文文本就顯得很有用了,因為英文單詞之間肯定都是會用空格隔開的麽。所以也希望大家養成好習慣,在一段文本中URL部分和文本之間用空格隔開。

PS:識別一個郵件地址變成email則可以這麼干

var text = "你好,我是一段文本。我的email地址:test@test.com";
var regexp = /[a-z0-9_\-+=.]+@[a-z0-9\-]+(\.[a-z0-9-]+)+/ig;
text = text.replace(regexp,function(h){return"<a href='mailto:"+h+"'>"+h+"</a>"});
console.log(text);

大家的意見以及建議呢?

12 Responses to 匹配一段文本中URL的正則問題

  1. Kars says:

    正好需要啊!及時雨!

  2. 路人甲 says:

    欣賞樓主,支持樓主,頂樓主!你太帥了!

  3. 光電轉速表 says:

    又學了一招

  4. 博主辛苦了。小弟路過

  5. 什麼 says:

    真的這樣就行了么

  6. 安卓匯 says:

    學習了,正好要用到這個,謝謝

  7. mz says:

    這幾條正則考慮得還不是很完整
    如果有
    http://中文網站。com/flkasjd/ 這樣的無聊網址的話就出錯啦(中文網址基本沒見過啊),不過這樣有些鑽牛角尖 😯 。
    所以添上判斷比較好
    (\w+\:\/{2}[\w.]+\/[^'"\s]+)

  8. 很實用的一個技巧

  9. Pingback: Homepage

Leave a Reply

Your email address will not be published. Required fields are marked *