2012-06-17 35 views
3

我想实现非常宽松的正则表达式为使用PHP的聊天客户端匹配。Twitter的样式URL正则表达式匹配

聊天客户端必须能够获取完整和不完整的URL。

例如:

http://www.example.comwww.example.comexample.com

我已成立,试图实现这一的preg_replace:

$find = array("/([\w]+:\/\/[\w-?&;#~=\.\/\@]+[\w\/])/is","/(^(?!http:\/\/)[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,4}(\/?\S*)?)/is"); 
$replace = array("<a target=\"_blank\" href=\"http://\\1\">\\1</a>","<a target=\"_blank\" href=\"\\1\">\\1</a>"); 
$output = preg_replace($find, $replace, $input); 

所以,目的是第一次发现“完整“与协议的URL,然后尝试找到没有协议的”懒惰“URL。

目前它适用于“完整”网址,但“懒惰”网址不会被拾取。

任何帮助将不胜感激。

谢谢。

+1

第二种类型,以“www”开头非常简单,但第三种类型更难以避免产生误报。我对第二种类型使用以下内容:'/ \ b(www \。[a-zA-Z0-9 \/\\\:\?\%\。\&\; =#\ - \ _ \!\ + \〜\,] *)/ i'没有测试,可能是最初的www \。可以删除给第三种类型? – tamouse

+0

嘿Tamouse,工作得很好。它似乎不会干扰其他正则表达式。请回答,我会接受。 – Moe

+0

行..所以它似乎干扰了“完整的”RegEx查找程序。有没有办法阻止它从以http://' – Moe

回答

1

所以经过几个小时的辛苦工作之后,我设法找到了一个相对简单的方法来匹配http:// URL和www。为了把它们变成锚点的URL。

这是最终的解决方案:

$output = preg_replace("/\b((http(s)?:\/\/)?(www\.[a-zA-Z0-9\/\\\:\?\%\.\&\;=#\-\_\!\+\~\,]*))/is","<a target=\"_blank\" href=\"http$3://$4\">$0</a>",$output); 

感谢tamouse的正则表达式。

5

我刚刚设置了类似的东西。我的想法是......任何以协议标识符或“www”开头的内容都是一个URL,以及任何与以有效TLD结尾的域名(两个字母或已知的通用顶级域名(gTLD))匹配的任何内容。域本身就是域。

$gtlds="com|net|org|biz|edu|gov|int|pro|xxx"; 
$gtlds+="|aero|arpa|asia|coop|museum|name|travel"; 
#$gtlds+="|xn-[a-z0-9]+"; 
$a = array(
    '/(f|ht)tps?:\/\/[^ ]+/', 
    '/(ftp|www)\.[a-z0-9.-]+(/[^ ]*)/', 
    "/([a-z0-9][a-z0-9-]*\.)+([a-z]{2}|$gtlds)\/[^ ]*/" 
); 

注意,我是一个老派的正则表达式的用户,所以这是ERE,而不是花哨的东西PREG所有的孩子都使用这些天。

通用顶级域名的荒谬列表来自IANA。我已经更新了它,所以除了.XN--*之外,这个答案的时间是有效的。如果您愿意,可以包含以.XN--开头的顶级域名列表,或者使用模式,或直接匹配它们并增大变量$gtlds。我从来没有遇到任何由于忽视它们而存在的问题,所以这就是我的策略。

上述REs适用于我的特定用途。我不会声称他们会为每一件不属于我的案件工作。 (例如,如果一个域或URL被引用,它们将包括尾部引号,这是我不得不处理的,所以我没有处理它。)

请注意,当你在做你的替换,而您希望您的生成器定位点的HREF属性是您匹配或生成的URL,您可能希望原样保留原始文本以用于布局和显示。

而根据你如何使用这些,字边界可能有帮助......但你已经知道如何做到这一点。

+0

开始的匹配开始,因为顶级域名白名单将变得非常无用,IANA最近更改了策略,并将新顶级域名向最高出价者拍卖。 – damianb

+0

因此,我的附带条件是“***在回答***时有效”。 – ghoti

+0

很好的答案,但不是真的我在找什么。使用Preg的任何不需要域名列表的东西? – Moe