我正在构建代码匹配并替换几种类型的模式(bbCode)。我正在努力做的一个匹配是[url = http:example.com]用锚链接取代所有。我也试图匹配并用锚链接替换纯文本URL。而这两者的结合是我遇到麻烦的地方。
由于我的例程是递归的,匹配并替换每个运行的整个文本,我无法替换已经包含在锚点中的URL。
这是我正在运行的递归例程:
if(text.search(p.pattern) !== -1) {
text = text.replace(p.pattern, p.replace);
}
到目前为止,这是我对普通网址的正则表达式:
/(?!href="|>)(ht|f)tps?:\/\/.*?(?=\s|$)/ig
网址可以以http或https或ftp或ftps开头,之后包含任何文字,以空格或标点符号结尾(./!/?/,)
为了绝对清楚,我正在使用它作为匹配的测试:
应匹配:
不匹配
我真的很乐意接受我能得到的任何帮助。
修改 以下jkshah首先接受的解决方案确实存在一些缺陷。例如,它将匹配
<img src="http://www.example.com/test.jpg">
然而,杰瑞的解决方案中的评论确实让我想再次尝试,而且该解决方案也解决了这个问题。因此我接受了这个解决方案。谢谢大家对此的帮助。 :)
答案 0 :(得分:3)
也许是这样的?
/(?:(?:ht|f)tps?:\/\/|www)[^<>\]]+?(?![^<>\]]*([>]|<\/))(?=[\s!,?\]]|$)/gm
然后在最后修剪点数。
虽然如果链接包含更多标点符号,但可能会导致一些问题...我会建议首先捕获链接,然后删除第二次替换的尾随标点符号。
[^<>\]]+
将匹配除<
,>
和]
(?![^<>\]]*([>]|<\/))
阻止匹配html标记之间的链接。
(?=[\s!,?\]]|$)
用于标点符号和空格。
答案 1 :(得分:1)
以下正则表达式应该可行。它会为您的样本输入提供所需的结果。
/((?:(?:ht|f)tps?:\/\/|www)[^\s,?!]+(?!.*<\/a>))/gm
在行动here
中查看 (?!.*<\/a>)
- 锚点的预示性
匹配内容将存储在$1
中,可用于替换字符串。
修改强>
要使用<img src ..
以下内容不匹配,可以使用
(^(?!.*<img\s+src)(?:(?:ht|f)tps?:\/\/|www)[^\s,?!]+(?!.*<\/a>))
答案 2 :(得分:0)
p.replace
能成为一种功能吗?如果是的话:
var text = 'http://www.example.com \n' +
'http://www.example.com/test \n' +
'http://example.com/test \n' +
'www.example.com/test \n' +
'<a href="http://www.example.com">http://www.example.com </a>\n' +
'<a href="http://www.example.com/test">http://www.example.com/test </a>\n' +
'<a href="http://example.com/test">http://example.com/test </a>\n' +
'<a href="www.example.com/test">www.example.com/test </a>';
var p = {
flag: true,
pattern: /(<a[^<]*<\/a>)|((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);
}
我添加的正则表达式部分是(<a[^<]*<\/a>)|
来检查url是否在锚点内的任何位置,如果是,那么替换函数会忽略它。
如果您想避免<a href="...">
内的网址,但要替换其中的其他网址,请将(<a[^<]*<\/a>)|
更改为(<a[^>]*>)|