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

Detect url / links and replace image with img tag and links with a href

本文关键字:替换 链接 图像 href 标签 并用 检测 img      更新时间:2023-09-26

我正在尝试编写一个函数,该函数将获取字符串,对其进行解析,并将图像网址替换为<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>

来自 RegExp.test()

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

RegExp.lastIndex

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

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

所以基本上当你有一个正则表达式的实例时,每次调用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;