如何使用Regex& amp ;;验证域名PHP?

时间:2010-06-12 00:00:55

标签: php regex preg-match

我想要一个解决方案,只验证域名不是完整的网址,以下示例是我正在寻找的:

domain.com -> true
domain.net -> true
domain.org -> true
domain.biz -> true
domain.co.uk -> true
sub.domain.com -> true
domain.com/folder -> false
domµ*$ain.com -> false

谢谢

6 个答案:

答案 0 :(得分:73)

所选答案不完整/错误。

正则表达式;

  • 不应验证以下域名:
    -domain.comdomain--.com-domain-.-.comdomain.000等......

  • 验证以下域名:
    schools.k12newTLD.clothinggood.photography等......

经过一些进一步的研究后;下面是我能提出的最正确,跨语言和紧凑的模式:

^(?!\-)(?:[a-zA-Z\d\-]{0,62}[a-zA-Z\d]\.){1,126}(?!\d+)[a-zA-Z\d]{1,63}$

此模式符合规范中定义的大多数*规则:

  • 每个标签/级别(由点分割)最多可包含 63个字符
  • 完整域名最多可包含 127个级别
  • 完整域名的文字表示不得超过 253个字符的长度。
  • 每个标签可以包含字母,数字和连字符
  • 标签不能用连字符开始结束
  • 顶级域名(扩展名)不能为全数字

注1 :正则表达式中不包含完整的域长度检查。应该通过本机方法简单地检查,例如strlen(domain) <= 253
注2 :此模式适用于大多数语言,包括PHP,Javascript,Python等......

参见DEMO here(适用于JS,PHP,Python)

更多信息:

  • 上面的正则表达式不支持IDN s。

  • 没有规格称扩展名(TLD)应介于2到6个字符之间。它实际上支持63个字符。查看当前的TLD list here。此外,一些网络在内部使用自定义/伪TLD。

  • 注册机构可能会强制使用此正则表达式中未明确支持的额外specific rules。例如,.CO.UK.ORG.UK必须至少包含3个字符,但少于23个字符,不包括扩展名。这些规则是非标准的,可能会有变化。如果你不能维护,不要实施它们。

  • 正则表达式很棒但不是解决每个问题的最有效,最佳的解决方案。因此,应尽可能使用本机URL解析器。例如Python的urlparse()方法或PHP的parse_url()方法......

  • 毕竟,这只是一种格式验证。正则表达式测试不确认域名实际配置/存在!你应该通过提出请求来测试存在。

Specs&amp;参考文献:

答案 1 :(得分:22)

怎么样:

^(?:[-A-Za-z0-9]+\.)+[A-Za-z]{2,6}$

答案 2 :(得分:1)

就我而言,如果格式为stackoverflow.com或xxx.stackoverflow.com,则域名被视为有效

所以除了其他堆栈答案之外,我还添加了对www的检查。也。

function isValidDomainName($domain) {
  if (filter_var(gethostbyname($domain), FILTER_VALIDATE_IP)) {
      return (preg_match('/^www./', $domain)) ? FALSE : TRUE;
  }
  return FALSE;
}

您可以使用此代码

测试该功能
    $domain = array("http://www.domain.com","http://www.domain.com/folder" ,"http://domain.com", "www.domain.com", "domain.com/subfolder", "domain.com","sub.domain.com");
    foreach ($domain as $v) {
        echo isValidDomainName($v) ? "{$v} is valid<br>" : "{$v} is invalid<br>";
    }

答案 3 :(得分:1)

请尝试以下表达式:

^(http[s]?\:\/\/)?((\w+)\.)?(([\w-]+)?)(\.[\w-]+){1,2}$

它实际上做了什么

  • 可选的http / s://
  • 可选www
  • 任何有效的字母数字名称(包括 - 和_)
  • 出现1或2次有效的字母数字名称(包括 - 和_)

验证示例

答案 4 :(得分:0)

请记住,正则表达式只能检查某些内容是否形成良好。 “www.idonotexistbecauseiammadeuponthespot.com”形式良好,但实际上并不存在......在撰写本文时。 ;)此外,某些免费的网络托管服务提供商(如Tripod)允许子域中的下划线。这显然违反了RFC,但它有时会起作用。

您想检查域名是否存在?试试dns_get_record而不是(只)一个正则表达式。

答案 5 :(得分:0)

我做了一个函数来验证域名而没有任何正则表达式。

<?php
function validDomain($domain) {
  $domain = rtrim($domain, '.');
  if (!mb_stripos($domain, '.')) {
    return false;
  }
  $domain = explode('.', $domain);
  $allowedChars = array('-');
  $extenion = array_pop($domain);
  foreach ($domain as $value) {
    $fc = mb_substr($value, 0, 1);
    $lc = mb_substr($value, -1);
    if (
      hash_equals($value, '')
      || in_array($fc, $allowedChars)
      || in_array($lc, $allowedChars)
    ) {
      return false;
    }
    if (!ctype_alnum(str_replace($allowedChars, '', $value))) {
      return false;
    }
  }
  if (
    !ctype_alnum(str_replace($allowedChars, '', $extenion))
    || hash_equals($extenion, '')
  ) {
    return false;
  }
  return true;
}
$testCases = array(
  'a',
  '0',
  'a.b',
  'google.com',
  'news.google.co.uk',
  'xn--fsqu00a.xn--0zwm56d',
  'google.com ',
  'google.com.',
  'goo gle.com',
  'a.',
  'hey.hey',
  'google-.com',
  '-nj--9*.vom',
  ' ',
  '..',
  'google..com',
  'www.google.com',
  'www.google.com/some/path/to/dir/'
);
foreach ($testCases as $testCase) {
  var_dump($testCase);
  var_dump(validDomain($TestCase));
  echo '<br /><br />';
}
?>

此代码输出:

  

string(1)“a”bool(false)
  
  string(1)“0”bool(false)
  
  string(3)“a.b”bool(true)
  
  string(10)“google.com”bool(true)
  
  string(17)“news.google.co.uk”bool(true)
  
  string(23)“xn - fsqu00a.xn - 0zwm56d”bool(true)
  
  string(11)“google.com”bool(false)
  
  string(11)“google.com”。布尔(真)
  
  string(11)“goo gle.com”bool(false)
  
  string(2)“a。”布尔(假)
  
  string(7)“hey.hey”bool(true)
  
  string(11)“google-.com”bool(false)
  
  string(11)“ - nj - 9 * .vom”bool(false)
  
  string(1)“”bool(false)
  
  string(2)“..”bool(false)
  
  string(11)“google..com”bool(false)
  
  string(14)“www.google.com”bool(true)
  
  string(32)“www.google.com/some/path/to/dir/”bool(false)

我希望如果我遗漏了一些东西,请告诉我,我可以改进这个功能。 :)