2012-08-08 134 views
4

我想包裝任何在一些文本中的網址,並將其變成超鏈接...但我不想包裝已被超鏈接包裝的網址。正則表達式來匹配網址,但不是超鏈接中的網址

例如:

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

下面的代碼:

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>"); 
} 

提供了以下的輸出:

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

我如何可以修改正則表達式來排除已經超鏈接的網址嗎?

由於

答案:

新方法是:

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

上面的代碼用作必需的。我從評論中的鏈接修改了正則表達式,因爲它包含了一個包含句號的錯誤,現在它排除了完整URL後面的任何完整句號。

+1

您不應該使用正則表達式來解析html。 http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags – 2012-08-08 11:52:22

+1

與[此問題]類似(http://stackoverflow.com/q/2177142/615754 )。和[這個其他問題](http://stackoverflow.com/questions/8038910/regex-to-find-urls-not-in-tags?rq=1)。或[這一個](http://stackoverflow.com/q/2641582/615754)。 – nnnnnn 2012-08-08 11:56:03

+0

優秀!謝謝nnnnnn。我今天早上搜索了搜索詞,但顯然我的搜索短語與任何有用的東西都不匹配。感謝分享! – Base33 2012-08-08 11:59:33

回答

2

由於javascript doesn't seem to support negative look-behind,你將不得不欺騙它通過使用替換功能。 奪href(也許你應該也還考慮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>" 
    }); 
} 

demo

編輯

A 「更好」 的版本,這將只是替代實際文本節點的鏈接:

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")) 

查看demo

+0

真的很好的答案。我發現了另一個功能,但最好的答案是一個 – Base33 2012-08-08 14:07:25