关于javascript:URL替换为锚,而不是替换现有的锚

URL replace with anchor, not replacing existing anchors

我正在构建代码匹配和替换几种类型的模式(bbcode)。我尝试进行的匹配之一是用锚链接替换所有链接。我还尝试用锚链接来匹配和替换纯文本URL。这两者的结合,就是我遇到麻烦的地方。

由于我的例程是递归的,每次运行都要匹配和替换整个文本,所以我很难不替换已经包含在锚中的URL。

这是我正在运行的递归例程:

1
2
3
if(text.search(p.pattern) !== -1) {
    text = text.replace(p.pattern, p.replace);
}

这是目前为止我对普通URL的regexp:

1
/(?!href="|>)(ht|f)tps?:\/\/.*?(?=\s|$)/ig

URL可以以http、https、ftp或ftps开头,然后包含任何文本,以空格或标点符号()结尾。!?)

为了绝对清楚起见,我将此作为匹配测试:

应匹配:

  • http://www.example.com
  • http://www.example.com/test/测试
  • http://example.com/test/测试
  • www.example.com/test测试

不应匹配

  • http://www.example.com
  • http://www.example.com/test/测试
  • http://example.com/test/测试
  • www.example.com/test测试

我真的会理解我能得到的任何帮助。

编辑下面的jkshah所接受的第一个解决方案确实存在一些缺陷。例如,它将匹配

1
<img src="http://www.example.com/test.jpg">

然而,杰瑞的解决方案中的评论确实让我想再试一次,而且这个解决方案也解决了这个问题。因此,我接受了这个解决方案。谢谢你们在这方面的帮助。:)


也许是这样?

1
/(?:(?:ht|f)tps?:\/\/|www)[^<>\]]+?(?![^<>\]]*([>]|<\/))(?=[\s!,?\]]|$)/gm

如果有的话,修剪末端的圆点。

Regex101演示

不过,如果链接包含更多标点符号,可能会导致一些问题…然后我建议先捕获链接,然后用第二个替换项删除尾随标点。

[^<>\]]+将匹配除<>]以外的所有字符。

(?![^<>\]]*([>]|<\/))防止HTML标记之间的链接匹配。

(?=[\s!,?\]]|$)用于标点和空白。


遵循regex应该有效。它在你的样本输入上给出了期望的结果。

1
/((?:(?:ht|f)tps?:\/\/|www)[^\s,?!]+(?!.*<\/a>))/gm

在这里看到它的作用

(?!.*<\/a>)—锚点的负面展望

匹配内容将存储在$1中,并可用于替换字符串。

编辑

为了与的内容不匹配,可以使用以下内容

1
(^(?!.*<img\s+src)(?:(?:ht|f)tps?:\/\/|www)[^\s,?!]+(?!.*<\/a>))


p.replace能成为函数吗?如果是这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
var text = 'http://www.example.com
'
+
           'http://www.example.com/test
'
+
           'http://example.com/test
'
+
           'www.example.com/test
'
+
           'http://www.example.com
'
+
           'http://www.example.com/test
'
+
           'http://example.com/test
'
+
           'www.example.com/test ';
var p = {
    flag: true,
    pattern: /()|((ht|f)tps?:\/\/|www\.).*?(?=\s|$)/ig,
    replace: function ($0, $1) {
                 if ($1) {
                     return $0;
                 } else {
                     p.flag = true;
                     return"construct replacement string here";
                 }
    }
};
while(p.flag){
    p.flag = false;
    text = text.replace(p.pattern, p.replace);
}

我添加的regex部分是()|,用于检查URL是否位于锚内,如果是,则替换函数将忽略它。

如果要避免中的URL,但要替换锚内的其他URL,则将()|更改为(]*>)|