正则表达式正则表达式匹配大多数URL需要改进

时间:2012-03-28 16:36:40

标签: php regex function url double-quotes

我需要一个能够检查字符串中现有URL的函数。

function linkcleaner($url) {
$regex="(?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))";

if(preg_match($regex, $url, $matches)) {
echo $matches[0];
}
}

正则表达式取自John Gruber's blog,在那里他解决了创建匹配所有URL的正则表达式的问题。 不幸的是,我无法使其发挥作用。似乎问题来自正则表达式中的双引号或表达式末尾的其他符号符号。 任何帮助表示赞赏。 谢谢!

4 个答案:

答案 0 :(得分:3)

您需要使用"

转义\

答案 1 :(得分:2)

除了@ tandu的回答,你还需要在php中使用正则表达式的分隔符。

最简单的方法是使用#开始和结束您的模式,因为该字符不会出现在其中:

$regex="#(?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'\".,<>?«»“”‘’]))#";

答案 2 :(得分:1)

Jack Maney的评论...... EPIC:D

更严重的是,它不起作用,因为你在中间终止了字符串文字。

要在字符串中包含双引号("),您需要使用\

转义它

所以,该行将是

$regex="/(?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'\".,<>?«»“”‘’]))/";

注意我也逃过了(')。这适用于在2个单引号之间定义字符串的时候。

答案 3 :(得分:1)

我不确定你们是如何阅读这个正则表达式的,因为阅读/修改是真正的痛苦......;)

尝试这个(这不是一个单行,是的,但如果需要,它很容易理解和修改):

<?php
$re_proto = "(?:https?|ftp|gopher|irc|whateverprotoyoulike)://";
$re_ipv4_segment = "[12]?[0-9]{1,2}";
$re_ipv4 = "(?:{$re_ipv4_segment}[.]){3}".$re_ipv4_segment;
$re_hostname = "[a-z0-9_]+(?:[.-][a-z0-9_]+){0,}";
$re_hostname_fqdn = "[a-z0-9_](?:[a-z0-9_-]*[.][a-z0-9]+){1,}";
$re_host = "(?:{$re_ipv4}|{$re_hostname})";
$re_host_fqdn = "(?:{$re_ipv4}|{$re_hostname_fqdn})";
$re_port = ":[0-9]+";
$re_uri = "(?:/[a-z0-9_.%-]*){0,}";
$re_querystring = "[?][a-z0-9_.%&=-]*";
$re_anchor = "#[a-z0-9_.%-]*";
$re_url = "(?:(?:{$re_proto})(?:{$re_host})|{$re_host_fqdn})(?:{$re_port})?(?:{$re_uri})?(?:{$re_querystring})?(?:{$re_anchor})?";

$text = <<<TEXT
http://www.example.com
http://www.example.com/some/path/to/file.php?f1=v1&f2=v2#foo
http://localhost.localdomain/
http://localhost/docs/???
www....wwhat?
www.example.com
ftp://ftp.mozilla.org/pub/firefox/latest/
Some new Mary-Kate Olsen pictures I found: the splendor of the Steiner Street Picture of href… http://t.co/tJ2NJjnf
TEXT;

$count = preg_match_all("\01{$re_url}\01is", $text, $matches);
var_dump($count);
var_dump($matches);
?>