用于验证URL的PHP​​正则表达式

时间:2010-03-05 22:06:20

标签: php regex validation url backwards-compatibility

我正在寻找一个合适的正则表达式来匹配一个URL(一个完整的URL与方案,域,路径等) 我通常会使用filter_var,但在这种情况下我不能支持PHP< 5.2!

我在网上搜索过但找不到任何我有信心会万无一失的东西,而我在SO上找到的就是人们说要使用filter_var。

是否有人使用他们使用的正则表达式?

我的代码(只是为了让你看到我想要实现的目标):

function validate_url($url){
    if (function_exists('filter_var')){
        return filter_var($url, FILTER_VALIDATE_URL);
        }
    return preg_match(REGEX_HERE, $url);
    }

4 个答案:

答案 0 :(得分:2)

我已经创建了一个验证域名的解决方案。虽然它没有专门涵盖整个URL,但它非常详细和具体。您需要问自己的问题是,“为什么我要验证域名?”如果要查看域名是否确实存在,则需要确认域名(包括有效的TLD)。问题是,太多的开发人员采用([a-z] {2,4})的捷径并称之为好。如果你按照这些思路思考,那么为什么称它为URL验证?不是。它只是通过正则表达式传递URL。

我有一个开源类,它允许您不仅使用TLD管理的单一来源(iana.org)验证域,而且还将通过DNS记录验证域以确保它实际存在。 DNS验证是可选的,但域将基于TLD特别有效。

例如:example.ay不是有效域,因为.ay TLD无效。但是使用这里发布的正则表达式([a-z] {2,4}),它会通过。我对质量很感兴趣。我试着在我写的代码中表达这一点。其他人可能并不在意。因此,如果您只想“检查”URL,则可以使用这些响应中列出的示例。如果您确实想要在URL中验证域,则可以在我创建的类中执行此操作。它可以在以下位置下载: http://code.google.com/p/blogchuck/source/browse/trunk/domains.php

它根据RFC“验证”(使用松散术语)确定有效域的内容进行验证。简而言之,域类将执行以下操作: 域验证的基本规则

  • 必须至少有一个字符
  • 必须以字母或数字开头
  • 包含字母,数字和连字符
  • 必须以字母或数字结尾
  • 可能包含多个节点(即node1.node2.node3)
  • 每个节点最长只能为63个字符
  • 总域名最长只能为255个字符
  • 必须以有效的TLD结尾
  • 可以是IP4地址

只有在检查本地副本后,它还会下载主TLD文件iana.org的副本。如果您的本地副本在30天内过期,则会下载新副本。文件中的TLD将在REGEX中用于验证您要验证的域中的TLD。这可以防止.ay(和其他无效TLD)通过验证。

这是一段很长的代码,但考虑到它的作用非常紧凑。而且它是最准确的。这就是我之前提出这个问题的原因。你想做“验证”还是简单的“检查”?

答案 1 :(得分:1)

我看过一个可以实际验证任何类型的有效网址的正则表达式,但它只有两页...

您最好使用parse_url解析网址,然后检查所有必需的位是否按顺序排列。

<强>增加: 这是我的URL类的剪辑:

public static function IsUrl($test)
{
    if (strpos($test, ' ') > -1)
    {
        return false;
    }
    if (strpos($test, '.') > 1)
    {
        $check = @parse_url($test);
        return is_array($check)
            && isset($check['scheme'])
            && isset($check['host']) && count(explode('.', $check['host'])) > 1
}
    return false;
}

它测试给定的字符串,并在url中需要一些基础知识,即设置方案并且主机名中有一个点。

答案 2 :(得分:1)

您可以尝试this one。我自己没有尝试过,但它肯定是我见过的最大的正则表达式,哈哈。

^(?#Protocol)(?:(?:ht|f)tp(?:s?)\:\/\/|~\/|\/)?(?#Username:Password)(?:\w+:\w+@)?(?#Subdomains)(?:(?:[-\w]+\.)+(?#TopLevel Domains)(?:com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum|travel|[a-z]{2}))(?#Port)(?::[\d]{1,5})?(?#Directories)(?:(?:(?:\/(?:[-\w~!$+|.,=]|%[a-f\d]{2})+)+|\/)+|\?|#)?(?#Query)(?:(?:\?(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)(?:&(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)*)*(?#Anchor)(?:#(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)?$

答案 3 :(得分:0)

!(https?://)?([-_a-z0-9]+\.)*([-_a-z0-9]+)\.([a-z]{2,4})(/?)(.*)!i

我使用此正则表达式来验证URL。到目前为止,我没有一次失败:))