2011-08-23 132 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?来源=库