2011-08-23 48 views
3

我使用以下的函數來搜索文本鏈接並將它們轉換爲超鏈接。首先是正確的?它似乎工作,但你知道一個(可能畸形)的URL會打破這個功能?StackOverflow樣式A Href在正則表達式中自動鏈接

我的問題是是否有可能得到這個支持端口號,例如stackoverflow.com:80/index不會被轉換,因爲該端口不被視爲url的有效部分。

因此,總的來說,我正在尋找Stackoverflow風格的網址識別,我相信這是對Markdown的自定義添加。

/** 
    * Search for and create links from urls 
    */ 
    static public function autoLink($text) { 
    $pattern = "/(((http[s]?:\/\/)|(www\.))(([a-z][-a-z0-9]+\.)?[a-z][-a-z0-9]+\.[a-z]+(\.[a-z]{2,2})?)\/?[a-z0-9._\/~#&=;%+?-]+[a-z0-9\/#=?]{1,1})/is"; 
    $text = preg_replace($pattern, " <a href='$1'>$1</a>", $text); 
    // fix URLs without protocols 
    $text = preg_replace("/href='www/", "href='http://www", $text); 

    return $text; 
    } 

感謝您的時間,

+1

你的函數不適用於URL到子域名(例如'my.domain.com/mypage') – meagar

+3

你想要的東西有多準確? [www.ca](http://www.ca)完全有效的網址,但不是您期望定期看到的網址。有很多東西是主機名,但絕對看起來不像一個。 –

+0

理想情況下,覆蓋所有可能性,但我懷疑任何人都會指向像www.ca這樣的網址,看看堆棧溢出的效果如何,看起來非常好! –

回答

1

你也應該看看這個問題的答案:How to mimic StackOverflow Auto-Link Behavior


我已經結束了堆棧溢出和與同事交談的答案。下面的代碼是我們能想到的最好的代碼。

/** 
    * Search for and create links from urls 
    */ 
    static public function autoLink($text) { 
    $pattern = "/\b((?P<protocol>(https?)|(ftp)):\/\/)?(?P<domain>[-A-Z0-9\\.]+)[.][A-Z]{2,7}(([:])?([0-9]+)?)(?P<file>\/[-A-Z0-9+&@#\/%=~_|!:,\\.;]*)?(?P<parameters>\?[A-Z0-9+&@#\/%=~_|!:,\\.;]*)?/ise"; 
$text = preg_replace($pattern, "' <a href=\"'.htmlspecialchars('$0').'\">$0</a>'", $text); 

    // fix URLs without protocols 
    $text = preg_replace("#href='www#i", "href='http://www", $text); 
    $text = preg_replace("#href=['\"](?!(https?|ftp)://)#i", "href='http://", $text); 

    return $text; 
    } 
+0

當沒有協議時,此函數會將您的html擰緊:像www.google.com和[email protected]這樣的簡單鏈接會轉換爲錯誤的html代碼。 – bart

+0

在最終版本中,我放了一些檢查來防止這種情況發生。不幸的是,我不再有權限訪問。 –

+0

你是什麼意思「我不再有權限」?你可以把你的代碼放在github上... – bart

0

而不是寫你自己的autolinking常規,這基本上是一個自定義標記引擎的開始,你可能想使用一個開源的標記引擎,因爲它是少可能容易受到跨站點腳本攻擊的影響。 PHP的開源標記引擎的一個示例是PHP Markdown,它具有自動鏈接URL的能力,並基本上使用與Stack  溢出中使用的Markdown語法相同的語法。

請注意:在將文本粘貼到屬性或元素的內部文本中之前,應始終使用htmlspecialchars()轉義HTML特殊字符。

0
$pattern = "/\b(?P<protocol>https?|ftp):\/\/(?P<domain>[-A-Z0-9.]+)(([:])?([0-9]+)?)(?P<file>\/[-A-Z0-9+&@#\/%=~_|!:,.;]*)?(?P<parameters>\?[A-Z0-9+&@#\/%=~_|!:,.;]*)?/i"; 

將匹配:

http://www.scroogle.org/index.html

http://www.scroogle.org:80/index.html?來源=庫