您的[^<>]
開頭是一個消費模式,它匹配除<
和>
之外的任何字符,並且可以匹配更多,然後只是一個換行符。你把這個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>');
}
對於一個更全面的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*)[email protected])?(?:(?!(?: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>')
一個更簡單的,並且通常工作替代是協議到非後向除空白和<
/>
(儘可能多的與*
量詞)以外的任何字符匹配字字符(感謝\b
字邊界):
s.replace(/(^|[^<>])\b((?:https?|ftp):\/\/[^<>\s]+\b)/gi, '$1<a href="$2">$2</a>')
見regex demo here
我現在效果更好,但它似乎只匹配最後一個URL。如何替換(鏈接)textarea中的所有網址? – Roy
使用更好的正則表達式,檢查很多其他職位上SO:[*正則表達式查找字符串中的URL *](http://stackoverflow.com/questions/6038061/regular-expression-to-find-urls-within -a-string)可能會有所幫助。我只是試圖解決你的問題中描述的主要問題。 –
另一種方法是使用['.replace(/(^ | [^ <>])\ b((?:https?| ftp):\/\/[^ <> \ s] + \ b)/ gi ,'$ 1 $2')'](https://regex101.com/r/jWRHc1/1)。 –