PHP / RegEx - 通过检测.com/.net/.org/.edu等将URL转换为链接


PHP / RegEx - Convert URLs to links by detecting .com/.net/.org/.edu etc

我知道有很多问题要求帮助将URL转换为字符串中的可点击链接,但我还没有找到我想要的东西。

我希望能够匹配以下任何示例并将它们转换为可点击的链接:

http://www.domain.com
https://www.domain.net
http://subdomain.domain.org
www.domain.com/folder
subdomain.domain.net
subdomain.domain.edu/folder/subfolder
domain.net
domain.com/folder

我不想匹配随机.stuff.separd.with.periods。

编辑:请记住,这些URL需要在较大的"普通"文本字符串中找到。 例如,我想 domain.net 在"Hello! 快来 domain.net 看看吧!

我认为这可以通过正则表达式来实现,该正则表达式可以确定匹配的 url 是否包含 .com、.net、.org 或 .edu,后跟正斜杠或空格。 除了用户错别字之外,我无法想象任何其他情况下,有效的URL会有一个后跟其他任何东西。

我意识到那里有很多有效的域名后缀,但我不需要全部支持它们。 我可以选择在正则表达式中使用类似(com|net|org|edu)的东西来支持哪个。 不幸的是,我对正则表达式还不够熟练,不知道如何正确实现这一点。

我希望有人能帮助我找到一个正则表达式(用于 PHP 的preg_replace),它可以根据由一个或多个点连接的任何文本来匹配 URL,并且要么以指定的扩展名之一结尾,后跟空格,要么包含指定的扩展名之一,后跟斜杠和可能的文件夹。

我做了几次搜索,到目前为止还没有找到我要找的东西。 如果已经有一个SO帖子可以回答这个问题,我深表歉意。

提前谢谢。

--- 编辑 3 ---

经过几天的反复试验以及 SO 的一些帮助,以下是有效的方法:

preg_replace_callback('#('s|^)((https?://)?('w|-)+('.('w+|-)*)+(?<='.net|org|edu|com|cc|br|jp|dk|gs|de)(':[0-9]+)?(?:/[^'s]*)?)(?='s|'b)#is',
                create_function('$m', 'if (!preg_match("#^(https?://)#", $m[2]))
                return $m[1]."<a href='"http://".$m[2]."'">".$m[2]."</a>"; else return $m[1]."<a href='"".$m[2]."'">".$m[2]."</a>";'),
                $event_desc);

这是下面 anubhava 代码的修改版本,到目前为止似乎完全符合我的需求。 谢谢!

您可以使用此正则表达式:

#('s|^)((?:https?://)?'w+(?:'.'w+)+(?<='.(net|org|edu|com))(?:/[^'s]*|))(?='s|'b)#is

法典:

$arr = array(
'http://www.domain.com/?foo=bar',
'http://www.that"sallfolks.com',
'This is really cool site: https://www.domain.net/ isn''t it?',
'http://subdomain.domain.org',
'www.domain.com/folder',
'Hello! You can visit vertigofx.com/mysite/rocks for some awesome pictures, or just go to vertigofx.com by itself',
'subdomain.domain.net',
'subdomain.domain.edu/folder/subfolder',
'Hello! Check out my site at domain.net!',
'welcome.to.computers',
'Hello.Come visit oursite.com!',
'foo.bar',
'domain.com/folder',
);
foreach($arr as $url) {   
   $link = preg_replace_callback('#('s|^)((?:https?://)?'w+(?:'.'w+)+(?<='.(net|org|edu|com))(?:/[^'s]*|))(?='s|'b)#is',
           create_function('$m', 'if (!preg_match("#^(https?://)#", $m[2]))
               return $m[1]."<a href='"http://".$m[2]."'">".$m[2]."</a>"; else return $m[1]."<a href='"".$m[2]."'">".$m[2]."</a>";'),
           $url);
   echo $link . "'n";

输出:

<a href="http://www.domain.com/?foo=bar">http://www.domain.com/?foo=bar</a>
http://www.that"sallfolks.com
This is really cool site: <a href="https://www.domain.net">https://www.domain.net</a>/ isn't it?
<a href="http://subdomain.domain.org">http://subdomain.domain.org</a>
<a href="http://www.domain.com/folder">www.domain.com/folder</a>
Hello! You can visit <a href="http://vertigofx.com/mysite/rocks">vertigofx.com/mysite/rocks</a> for some awesome pictures, or just go to <a href="http://vertigofx.com">vertigofx.com</a> by itself
<a href="http://subdomain.domain.net">subdomain.domain.net</a>
<a href="http://subdomain.domain.edu/folder/subfolder">subdomain.domain.edu/folder/subfolder</a>
Hello! Check out my site at <a href="http://domain.net">domain.net</a>!
welcome.to.computers
Hello.Come visit <a href="http://oursite.com">oursite.com</a>!
foo.bar
<a href="http://domain.com/folder">domain.com/folder</a>

PS:此正则表达式仅支持URL中的http和https方案。所以例如:如果你也想支持ftp,那么你需要稍微修改正则表达式。

'/(http(s)?:'/'/)?['w'/'.]+('.((com)|(edu)|(net)|(org)))['w'/]*/'

这适用于您的示例。您可能希望在最后一个括号中添加对"-"、"&"、"?"、":"等的额外字符支持。

'/(http(s)?:'/'/)?['w'/'.]+('.((com)|(edu)|(net)|(org)))['w'/'?=&-;]*/'

这将支持参数和端口号。

例如:www.foo.ca:8888/test?param1=val1&param2=val2

非常感谢。我修改了他的最终解决方案,以允许所有域(.ca,.co.uk),而不仅仅是指定的域。

$html = preg_replace_callback('#('s|^)((https?://)?('w|-)+('.[a-z]{2,3})+(':[0-9]+)?(?:/[^'s]*)?)(?='s|'b)#is',
    create_function('$m', 'if (!preg_match("#^(https?://)#", $m[2])) return $m[1]."<a href='"http://".$m[2]."'" target='"blank'">".$m[2]."</a>"; else return $m[1]."<a href='"".$m[2]."'" target='"blank'">".$m[2]."</a>";'),
    $url);