匹配一段文本中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);

大家的意见以及建议呢?

  • 正好需要啊!及时雨!

  • Elicip

    :mrgreen:

  • 欣赏楼主,支持楼主,顶楼主!你太帅了!

  • 光电转速表

    又学了一招

  • http://www.beihaijia.com 可以跟您换下友情吗?

  • 博主辛苦了。小弟路过

  • 真的这样就行了么

  • 学习了,正好要用到这个,谢谢

  • 支持一个~~

  • mz

    这几条正则考虑得还不是很完整
    如果有
    http://中文网站。com/flkasjd/ 这样的无聊网址的话就出错啦(中文网址基本没见过啊),不过这样有些钻牛角尖 😯 。
    所以添上判断比较好
    (\w+\:\/{2}[\w.]+\/[^'"\s]+)

  • 很实用的一个技巧

  • Pingback: Homepage()