Regex matches urls but not urls in hyperlinks

I'm trying to wrap any url that is in some text and turn it into a hyperlink ... but I don't want to wrap a url that is already wrapped with a hyperlink.

For instance:

<a href="http://twitter.com">Go To Twitter</a> here is a url http://anotherurl.com 

The following code:

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

Gives the following output:

 <a href="<a href='http://twitter.com/twitter'>http://twitter.com/twitter</a>">@BIR</a> <a href="http://anotherurl.com">http://anotherurl.com</a> 

How to change the regular expression to exclude already hyperlinks to URL?

thanks

Answer:

New Method:

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

The code above functions as needed. I changed the regular expression from the link in the comments because it contained an error in which it would include a full stop, now it excludes any full stops that appear after the full URL.

+4
source share
1 answer

Since javascript does not support negative appearance , you will have to trick it using the replace function. Grab href (maybe you should also consider src ):

 function repl(text) { var exp = /((href|src)=["']|)(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; return text.replace(exp, function() { return arguments[1] ? arguments[0] : "<a href=\"" + arguments[3] + "\">" + arguments[3] + "</a>" }); } 

Watch the demo

EDIT

The "best" version, which will replace links only in real text nodes:

 function repl(node) { var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/i; var nodes=node.childNodes; for (var i=0, m=nodes.length; i<m; i++){ var n=nodes[i]; if (n.nodeType==n.TEXT_NODE) { var g=n.textContent.match(exp); while(g) { var idx=n.textContent.indexOf(g[0]); var pre=n.textContent.substring(0,idx); var t=document.createTextNode(pre); var a=document.createElement("a"); a.href=g[0]; a.innerText=g[0]; n.textContent = n.textContent.substring(idx+g[0].length); n.parentElement.insertBefore(t,n); n.parentElement.insertBefore(a,n); g=n.textContent.match(exp); } } else { repl(n); } } } var r=repl(document.getElementById("t")) 

See Demo

+2
source

All Articles