2008-11-13 85 views

回答

14

Jan Goyvaerts,RegexBuddy的創建者,擁有written a response給Jeff Atwood的博客,該博客解決Jeff提供的問題並提供了一個很好的解決方案。

\b(?:(?:https?|ftp|file)://|www\.|ftp\.)[-A-Z0-9+&@#/%=~_|$?!:,.]*[A-Z0-9+&@#/%=~_|$] 

爲了忽略發生的旁邊的一個「或>,您可以添加(?<![">])的正則表達式的開始比賽,所以你得到

(?<![">])\b(?:(?:https?|ftp|file)://|www\.|ftp\.)[-A-Z0-9+&@#/%=~_|$?!:,.]*[A-Z0-9+&@#/%=~_|$] 

這將匹配完整地址(http://.. )以及與WWW或FTP起始地址 - 你的運氣與地址一樣ars.userfriendly.org ...

0

無恥插頭:你可以看看這裏(regular expression replace a word by a link)爲靈感

這個問題要求用某個鏈接替換某個詞,除非已經存在鏈接。所以你遇到的問題或多或少是一回事。

您只需要一個匹配URL的正則表達式(代替單詞)。最簡單的假設是這樣的:一個URL(可選)以"http://","ftp://""mailto:"開頭,只要沒有空格字符,換行符,標記括號或引號就可以持續。

要小心,長的正則表達式在前面。不區分大小寫應用。

(href\s*=\s*['"]?)?((?:http://|ftp://|mailto:)?[^.,<>"'\s\r\n\t]+(?:\.(?![.<>"'\s\r\n])[^.,!<>"'\s\r\n\t]+)+) 

被警告 - 這也將匹配在技術上無效的網址,它可以識別things.formatted.like.this作爲URL。如果它太不靈敏,這取決於你的數據。如果你有例子返回誤報,我可以微調正則表達式。

正則表達式將產生兩個匹配組。第2組將包含匹配的東西,這很可能是一個URL。組1將包含一個空字符串或'href="'。你可以用它作爲一個指標,表明這個匹配發生在裏面現有鏈接的href參數,你不必觸摸那個。

一旦你確認此做正確的事你大部分時間(與用戶提供的數據,你永遠無法確定),你可以做其餘的兩個步驟,正如我在另議它問題:

  1. 讓周圍的每一個URL鏈接存在(除非有東西在比賽第1組!)這產生的事物,本來就有連桿雙嵌套<a>標籤。
  2. 掃描錯誤嵌套<a>標籤,去掉最裏面的一個
0

要跳過現有的只使用一個向後看 - 添加(?<!href=")到你的正則表達式的開始,所以它看起來是這樣的:

/(?<!href=")http://\S*/ 

顯然,這不是對找到所有類型的URL的完整的解決方案,但是這應該解決您與現有搞亂的問題。

10

我做了少許修改包含在原來的答案正則表達式:

(?<![.*">])\b(?:(?:https?|ftp|file)://|[a-z]\.)[-A-Z0-9+&#/%=~_|$?!:,.]*[A-Z0-9+&#/%=~_|$] 

,讓更多的子域,並可以運行在標籤更爲全面檢查。若要將此PHP的預浸料代替,你可以使用:

$convertedText = preg_replace('@(?<![.*">])\b(?:(?:https?|ftp|file)://|[a-z]\.)[-A-Z0-9+&#/%=~_|$?!:,.]*[A-Z0-9+&#/%=~_|$]@i', '<a href="\0" target="_blank">\0</a>', $originalText); 

注意,我刪除@從正則表達式,爲了使用它作爲一個的preg_replace分隔符。無論如何,@將很少用在URL中。

很明顯,你可以修改替換文本,並刪除目標=「_空白」,或添加相對=「nofollow」等

希望有所幫助。

+0

我剛開始添加的=在(?])不會打破link(不帶引號的錨標記)。尼斯正則表達式順便說一句:) – Joel 2010-06-29 10:41:41

+0

@Joel:你確定你希望lookbehind意思是「斷言在字符串中當前位置之前不可能匹配點,星號,引號或關閉角括號」嗎? – 2012-04-13 16:44:16

11

這條線程比較古老,但我在處理自己的問題時遇到了它:也就是說,將任何網址轉換爲鏈接,但不要將任何已經存在於錨定標記中的網址留下。過了一會兒,這是什麼彈出:

(?!(?!.*?<a)[^<]*<\/a>)(?:(?:https?|ftp|file)://|www\.|ftp\.)[-A-Z0-9+&#/%=~_|$?!:,.]*[A-Z0-9+&#/%=~_|$] 

用下面的輸入:

http://www.google.com 
http://google.com 
www.google.com 

<p>http://www.google.com<p> 

this is a normal sentence. let's hope it's ok. 

<a href="http://www.google.com">www.google.com</a> 

這是一個preg_replace函數的輸出:

<a href="http://www.google.com" rel="nofollow">http://www.google.com</a> 
<a href="http://google.com" rel="nofollow">http://google.com</a> 
<a href="www.google.com" rel="nofollow">www.google.com</a> 

<p><a href="http://www.google.com" rel="nofollow">http://www.google.com</a><p> 

this is a normal sentence. let's hope it's ok. 

<a href="http://www.google.com">www.google.com</a> 

只是想回貢獻爲了節省一些時間。

1
if (preg_match('/\b(?<!=")(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[A-Z0-9+&@#\/%=~_|](?!.*".*>)(?!.*<\/a>)/i', $subject)) { 
    # Successful match 
} else { 
    # Match attempt failed 
}