web-dev-qa-db-ja.com

Regex&Phpを使用してドメイン名を検証する方法は?

完全なURLではなくドメイン名のみを検証するソリューションが必要です。次の例は私が探しているものです。

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
18
Ryan

どうですか:

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

選択した回答は不完全/間違っています。

正規表現パターン。

  • 次のようなドメインを検証しないでください
    _-domain.com_、_domain--.com_、_-domain-.-.com_、_domain.000_など..

  • should次のようなドメインを検証する必要があります:
    _schools.k12_、_newTLD.clothing_、_good.photography_など..

いくつかのさらなる調査の後;以下は、私が思いつくことができる最も正確で、言語を超えたコンパクトなパターンです。

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

このパターンは、仕様で定義されているほとんどの*ルールに準拠しています。

  • 各ラベル/レベル(ドットで分割)には、最大63文字を含めることができます。
  • 完全なドメイン名には、最大127レベルを含めることができます。
  • 完全なドメイン名は、テキスト表現で253文字の長さを超えることはできません。
  • 各ラベルは、文字、数字、およびハイフンで構成できます。
  • ラベルは、ハイフンでstartまたはendすることはできません。
  • トップレベルドメイン(拡張機能)をall-numericにすることはできません。

注1:完全なドメイン長チェックは正規表現。ネイティブメソッドで簡単にチェックする必要があります。 strlen(domain) <= 253
注2:このパターンはほとんどの場合に機能しますPHP、Javascript、Pythonなどを含む言語...

DEMO here (JS、PHP、Pythonの場合)を参照してください

より詳しい情報:

  • 上記の正規表現は [〜#〜] idn [〜#〜] sをサポートしていません。

  • 拡張子(TLD)を2〜6文字にする必要があるという仕様はありません。実際には63文字をサポートしています。現在の TLDリストここ を参照してください。また、一部のネットワークは内部でカスタム/疑似TLDを使用します。

  • 登録局は、この正規表現で明示的にサポートされていない追加の 特定のルール を課す場合があります。たとえば、_.CO.UK_および_.ORG.UK_は、拡張子を含めずに3文字以上23文字未満である必要があります。これらの種類のルールは非標準であり、変更される可能性があります。維持できない場合は実装しないでください。

  • 正規表現は優れていますが、すべての問題に対して最も効果的でパフォーマンスの高いソリューションではありません。したがって、可能な限り、代わりにネイティブURLパーサーを使用する必要があります。例えばPythonの urlparse() メソッドまたはPHPの parse_url() メソッド..

  • 結局のところ、これは単なるフォーマット検証です。正規表現テストでは、ドメイン名が実際に構成されている/存在していることを確認しません。リクエストして存在をテストする必要があります。

仕様とリファレンス:

73

この式を試してください:

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

それが実際に何をするか

  • オプションのhttp/s://
  • オプションのwww
  • 有効な英数字の名前(-および_を含む)
  • 有効な英数字名(-および_を含む)が1回または2回出現する

検証例

1
rikworkshop.com

私の場合、形式が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>";
    }
1
Web_Developer

正規表現は、何かが適切に形成されているかどうかを確認することしかできないことを忘れないでください。 「www.idonotexistbecauseiammadeuponthespot.com」は整形式ですが、実際には存在しません...執筆時点では。 ;)さらに、特定の無料のWebホスティングプロバイダー(Tripodなど)では、サブドメインにアンダースコアを付けることができます。これは明らかにRFCの違反ですが、機能することもあります。

ドメインが存在するかどうかを確認しますか?正規表現の代わりに dns_get_record を試してください。

0
Charles

正規表現なしでドメイン名を検証する関数を作成しました。

<?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。" bool(true)

string(11) "goo gle.com" bool(false)

string(2) "a。" bool(false)

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)

何かを逃した場合は、すべてをカバーしたと思います。教えてください。この機能を改善できます。 :)

0