javascript:使用正则表达式匹配并替换textarea中未标记的URL

时间:2016-12-20 06:29:57

标签: javascript html regex

现在我用它来替换(链接)textarea中的URL以进行提交(textarea可能混有标记和未标记的URL):

function repl(text) {
  var exp = /[^<>]\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|](?![^<>])/gim;

  return text.replace(exp, '<a href="$&">$&</a>');
}

它有点工作,但在\nhref=""<a>的文本节点,这很烦人。

我尝试将正则表达式修改为没有结果\n,但我没有这样做。

任何人都可以帮我改进吗? (我在书签中使用它)

2 个答案:

答案 0 :(得分:2)

您的[^<>]在开头是一个消费模式,可以匹配<>以外的任何字符,并且可以匹配更多的新行。您将此char添加到href值中,其余的匹配字符串。

相反,捕获模式的其余部分:

/(^|[^<>])\b((?:https?|ftp):\/\/[a-z0-9+&@#\/%?=~_|!:,.;-]*[a-z0-9-+&@#\/%=~_|])(?![^<>])/gi
 ^^^^^^^^^  ^                                                                  ^

(^|[^<>])将是第1组,其余的将被捕获到第2组。在替换模式中使用$1$2反向引用将捕获的部分放入适当的位置:

function repl(text) {
  var exp = /(^|[^<>])\b((?:https?|ftp):\/\/[a-z0-9+&@#\/%?=~_|!:,.;-]*[a-z0-9-+&@#\/%=~_|])(?![^<>])/gi;
  return text.replace(exp, '$1<a href="$2">$2</a>');
}

要获得更全面的网址提取正则表达式,请参阅How can i extract URL's from a piece of text into an Array using JavaScript示例用法Diego Perini's URL regex。您可以将其调整为shown here

s.replace(/(^|[^<>])\b((?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[\/?#]\S*)?)(?![<>])/gi, '$1<a href="$2">$2</a>')

一个更简单且通常可行的替代方案是在协议之后匹配除空白之外的任何字符< / >(尽可能多地使用*量词) -word char(感谢\b字边界):

s.replace(/(^|[^<>])\b((?:https?|ftp):\/\/[^<>\s]+\b)/gi, '$1<a href="$2">$2</a>')

请参阅regex demo here

答案 1 :(得分:0)

感谢WiktorStribiżew的建议,我现在有一个完整的版本:

function repl(text) {
  var exp = /(^|[^<>"])\b((?:https?|ftp):\/\/[^<>\s]+\b)/gi;
  return text.replace(exp, '$1<a href="$2">$2</a>');
}