检测网址/链接并使用img标记替换图像并使用href链接

时间:2013-09-20 15:37:42

标签: javascript html regex image

我正在尝试编写一个函数,它会接受一个字符串,解析它,并用<img src="image"><a href="link">link</a>的链接替换图像网址。

这就是我所做的:

var __urlRegex = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
var __imgRegex = /^ftp|http|https?:\/\/(?:[a-z\-]+\.)+[a-z]{2,6}(?:\/[^\/#?]+)+\.(?:jpe?g|gif|png)$/ig;

function parseURL($string){
    var exp = __urlRegex;
    return $string.replace(exp,function(match){
            if(__imgRegex.test(match,contents)){
                return '<img src="'+contents+'" width="200" />';
            }
            else{
                return '<a href="'+contents+'" target="_blank">'+contents+'</a>';
            }
        }
    );
}

当我做一些测试时,正则表达式工作正常。然而,在实施时,有一些奇怪的mumbo jumbo正在发生。如果我在它上面说5个图像网址,它会将第1个图像作为图像进行解析,但第二个作为链接进行解析,这将继续进行!!

我哪里错了?

我用于测试的示例字符串:

This is a kitten http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg
with a sibling which is also a kitten http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg
and a sister which is also a kitten http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg
and lots of kittens
http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg
http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg
http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg
http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg

这是我得到的输出

<p>This is a kitten <img src="http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg" width="200">
with a sibling which is also a kitten <a href="http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg" target="_blank">http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg</a>
and a sister which is also a kitten <img src="http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg" width="200">
and lots of kittens
undefined
<img src="http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg" width="200">
<a href="http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg" target="_blank">http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg</a>
<img src="http://s3.amazonaws.com/rapgenius/filepicker%2FvCleswcKTpuRXKptjOPo_kitten.jpg" width="200"></p>

1 个答案:

答案 0 :(得分:3)

来自RegExp.test()

  

在同一个全局正则表达式上多次调用测试   实例将超过上一场比赛。

RegExp.lastIndex

  

读/写整数属性,指定开始下一个匹配的索引。

正如文档所指定的那样,lastIndex将存储test()将开始匹配的位置。

所以基本上当你有一个RegExp实例时,每次调用test()都会提升lastIndex。一旦找到第一次出现,它将超越它并尝试找到另一个匹配。好吧,已经没有了,所以它返回 false lastIndex重新设置为0,下一次调用test()将从头开始,它将返回 true ,依此类推......

因此,您需要将lastIndex属性重置为0,以便test()始终在下一个字符串的开头匹配。

__imgRegex.lastIndex=0;

JSFiddle DEMO

function parseURL($string){

    var exp = __urlRegex;
    return $string.replace(exp,function(match){
            __imgRegex.lastIndex=0;
            if(__imgRegex.test(match)){
                return '<img src="'+match+'" class="thumb" />';
            }
            else{
                return '<a href="'+match+'" target="_blank">'+match+'</a>';
            }
        }
    );
}

编辑:

您的正则表达式错误地将http://google.com与图像匹配。另外测试只需要一个参数。

__imgRegex.test('http://google.com') //true

由于您首先检查文本是否为链接,因此无需再次检查是否为链接,您只需检查其是否具有图像扩展名。

var __imgRegex = /\.(?:jpe?g|gif|png)$/i;