现在我用它来替换(链接)文本区域中的 URL 以进行提交(文本区域可能混合有标记和非标记 URL):
function repl(text) {
var exp = /[^<>]\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|](?![^<>])/gim;
return text.replace(exp, '<a href="$&">$&</a>');
}
它有点工作,但有 \n
里面href=""
和 <a>
的文本节点,这很烦人。
我尝试将正则表达式修改为不具有 \n
结果但我没能做到。
有人可以帮我改进这个吗? (我在书签中使用了它)
最佳答案
您的[^<>]
开头是一个与 <
以外的任何字符匹配的消费模式和>
,并且可以匹配更多内容而不仅仅是换行符。您将此字符放入 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>');
}
有关更全面的 URL 提取正则表达式,请参阅 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>')
一个更简单且通常可行的替代方案是匹配除空格和 <
之外的任何字符。/>
(尽可能多地使用 *
量词)在协议(protocol)之后直到非单词字符(感谢 \b
单词边界):
s.replace(/(^|[^<>])\b((?:https?|ftp):\/\/[^<>\s]+\b)/gi, '$1<a href="$2">$2</a>')
关于javascript:使用正则表达式匹配并替换文本区域中的非标记 URL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41236172/