我正在构建代码匹配和替换几种类型的模式(bbCode)。我试图进行的匹配之一是将 [url=http:example.com] 全部替换为锚链接。我还尝试用锚链接匹配和替换纯文本网址。这两者的结合就是我遇到麻烦的地方。
由于我的例程是递归的,每次运行都会匹配和替换整个文本,因此我无法替换锚点中已包含的网址。
这是我正在运行的递归例程:
if(text.search(p.pattern) !== -1) {
text = text.replace(p.pattern, p.replace);
}
这是迄今为止我的纯网址正则表达式:
/(?!href="|>)(ht|f)tps?:\/\/.*?(?=\s|$)/ig
URL 可以以 http 或 https 或 ftp 或 ftps 开头,后面包含任何文本,以空格或标点符号 (. / ! / ? / ,) 结尾
为了绝对清楚,我用它作为匹配测试:
应匹配:
不应该匹配
我真的很感谢我能在这里得到的任何帮助。
编辑 下面 jkshah 接受的第一个解决方案确实存在一些缺陷。例如,它将匹配
<img src="http://www.example.com/test.jpg">
Jerry 解决方案中的评论确实让我想再试一次,该解决方案也解决了这个问题。因此我接受了这个解决方案。感谢大家对此的热心帮助。 :)
也许是这样的?
/(?:(?:ht|f)tps?:\/\/|www)[^<>\]]+?(?![^<>\]]*([>]|<\/))(?=[\s!,?\]]|$)/gm
然后修剪末端的点(如果有)。
虽然如果链接包含更多标点符号,可能会导致一些问题...然后我建议首先捕获链接,然后通过第二次替换删除尾随标点符号。
[^<>\]]+
将匹配除 <
、>
和 ]
之外的所有字符
(?![^<>\]]*([>]|<\/))
防止 html 标签之间的链接匹配。
(?=[\s!,?\]]|$)
用于标点符号和空格。
遵循正则表达式应该可以工作。它为您的样本输入提供了所需的结果。
/((?:(?:ht|f)tps?:\/\/|www)[^\s,?!]+(?!.*<\/a>))/gm
查看实际操作此处
(?!.*<\/a>)
- 锚点的负前瞻
匹配的内容将存储在
$1
中,并可用于替换字符串。
编辑
要不与
<img src ..
匹配内容,可以使用以下
(^(?!.*<img\s+src)(?:(?:ht|f)tps?:\/\/|www)[^\s,?!]+(?!.*<\/a>))
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="...">
内的url,但要替换锚点内的其他url,则将(<a[^<]*<\/a>)|
更改为(<a[^>]*>)|
我也在寻找用于网址放置的锚文本。例如我的文字是 增强。