2

我正在尝试编写一个函数,该函数将接受一个字符串,对其进行解析,然后将图像 url 替换为 a<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>';
            }
        }
    );
}

当我进行一些测试时,正则表达式工作正常。然而,在实施过程中,会发生一些奇怪的胡言乱语。如果我向它抛出说 5 个图像 url,它会将第一个解析为图像,而将第二个解析为链接,然后交替进行!

我哪里错了?

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

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

1 回答 1

3

来自RegExp.test()

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

正则表达式.lastIndex

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

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

所以基本上当你有一个 RegExp 的实例时,每次调用test()都会推进lastIndex。一旦它找到第一个匹配项,它就会超越它并尝试找到另一个匹配项。好吧,没有了,所以它返回falselastIndex被重新设置为0,下一次调用test ()将从头开始,它将返回true等等......

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

__imgRegex.lastIndex=0;

JSFiddle 演示

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;
于 2013-09-20T17:31:24.503 回答