PHP Regex用于提取任意域的子域

时间:2010-11-29 14:10:36

标签: php regex

我想为具有任意顶级扩展名的域提取子域和域部分。

因此:

sub1.domain1.com - >提取subdomain = sub1,domain = domain1.com

sub2.domain2.co.in - >提取subdomain = sub2,domain = domain2.co.in

sub3.domain3.co.uk - >提取subdomain = sub3,domain = domain3.co.uk

sub4.domain4.us - >提取subdomain = sub4,domain = domain4.us

mydomain.com - >提取subdomain =“”,domain = mydomain.com

mydomain.co.in - >提取subdomain =“”,domain = mydomain.co.in

我对如何处理像co.in/co.uk等TLD这一点感到困惑。我可以通过测量最后5个字符中是否有DOT(。)来使用暴力方法来做到这一点,但想想是否有是一种正则表达方式。


注1:正如TToni指出的那样,可能存在歧义。但是,我会提出一些限制:

1)“域名”部分(没有扩展名) - >将至少4个字符。

2)TLD扩展部分(.com,co.in,.us等)要么有一个 DOT ,要么它有两个 DOTS ,那么倒数第二部分(子TLD)最多有3个字符。

我有一种感觉,这些约束会使用正则表达式解决问题,并且可以解决问题。

(另外,假设已经删除了“www。”)。


注2:

上述约束的例子

sub.dom.in - >域= “sub.dom.in”

sub.dom1.in - > domain =“dom1.in”,subdomain =“sub”

这可能听起来很麻烦,但原因是 - 我希望这是出于我的内部目的,并且我的所有域中至少有4个字符,并且,所有扩展都有单个DOT或倒数第二个部分是最多3个字符


注3:我觉得我可能会因为使用正则表达式而犯错误。因此想着做字符串搜索方式。

的问候,

JP

4 个答案:

答案 0 :(得分:4)

不确定您是否需要正则表达式。将域名拆分为“。”然后根据最右边的位应用一些启发式算法 - 例如,如果last是“com”,那么domain是last + second last,subdomain是其余的。

或保留“顶级”列表(引用因为它与普通顶级域名的含义不同),遍历与域名右端匹配的列表。如果匹配,删除顶级位并将其余部分作为子域返回 - 这可以放在正则表达式但是不清楚。该列表看起来像

".edu", ".gov", ".mil", ".com", ".co.uk", ".gov.uk", ".nhs.uk", [...]

正则表达式看起来像

 \.(edu|gov|mil|com|co\.uk|gov\.uk|nhs\.uk|[...])$

答案 1 :(得分:0)

您可以使用:(\b\w+\b(?:\.\b\w+\b)*?){0,1}?\.?(\b\w+\b(?:\.\b\w{1,3}\b)?\.\b\w{1,3}\b)
它看起来不是很漂亮,但它背后的想法很简单。它将捕获第一组中的子域和第二组中的域。它还会将“sub1.sub2.sub3.domain2.co.in”等内容分成“sub1.sub2.sub3”和“domain2.co.in”

答案 2 :(得分:0)

我获得了“顶级”域名,它可能很丑,但它确实有效。

$fix = array('com', 'edu', 'gov', 'int', 'mil', 'net', 'org', 'biz', 'info', 'pro', 'name', 'museum', 'coop', 'aero', 'x    xx', 'idv', 'al', 'dz', 'af', 'ar', 'ae', 'aw', 'om', 'az', 'eg', 'et', 'ie', 'ee', 'ad', 'ao', 'ai', 'ag', 'at', 'au',     'mo', 'bb', 'pg', 'bs', 'pk', 'py', 'ps', 'bh', 'pa', 'br', 'by', 'bm', 'bg', 'mp', 'bj', 'be', 'is', 'pr', 'ba', 'pl',     'bo', 'bz', 'bw', 'bt', 'bf', 'bi', 'bv', 'kp', 'gq', 'dk', 'de', 'tl', 'tp', 'tg', 'dm', 'do', 'ru', 'ec', 'er', 'fr',     'fo', 'pf', 'gf', 'tf', 'va', 'ph', 'fj', 'fi', 'cv', 'fk', 'gm', 'cg', 'cd', 'co', 'cr', 'gg', 'gd', 'gl', 'ge', 'cu',     'gp', 'gu', 'gy', 'kz', 'ht', 'kr', 'nl', 'an', 'hm', 'hn', 'ki', 'dj', 'kg', 'gn', 'gw', 'ca', 'gh', 'ga', 'kh', 'cz',     'zw', 'cm', 'qa', 'ky', 'km', 'ci', 'kw', 'cc', 'hr', 'ke', 'ck', 'lv', 'ls', 'la', 'lb', 'lt', 'lr', 'ly', 'li', 're',     'lu', 'rw', 'ro', 'mg', 'im', 'mv', 'mt', 'mw', 'my', 'ml', 'mk', 'mh', 'mq', 'yt', 'mu', 'mr', 'us', 'um', 'as', 'vi',     'mn', 'ms', 'bd', 'pe', 'fm', 'mm', 'md', 'ma', 'mc', 'mz', 'mx', 'nr', 'np', 'ni', 'ne', 'ng', 'nu', 'no', 'nf', 'na',     'za', 'aq', 'gs', 'eu', 'pw', 'pn', 'pt', 'jp', 'se', 'ch', 'sv', 'ws', 'yu', 'sl', 'sn', 'cy', 'sc', 'sa', 'cx', 'st',     'sh', 'kn', 'lc', 'sm', 'pm', 'vc', 'lk', 'sk', 'si', 'sj', 'sz', 'sd', 'sr', 'sb', 'so', 'tj', 'tw', 'th', 'tz', 'to',     'tc', 'tt', 'tn', 'tv', 'tr', 'tm', 'tk', 'wf', 'vu', 'gt', 've', 'bn', 'ug', 'ua', 'uy', 'uz', 'es', 'eh', 'gr', 'hk',     'sg', 'nc', 'nz', 'hu', 'sy', 'jm', 'am', 'ac', 'ye', 'iq', 'ir', 'il', 'it', 'in', 'id', 'uk', 'vg', 'io', 'jo', 'vn',     'zm', 'je', 'td', 'gi', 'cl', 'cf', 'cn', 'ac', 'ad', 'ae', 'af', 'ag', 'ai', 'al', 'am', 'an', 'ao', 'aq', 'ar', 'as',     'at', 'au', 'aw', 'az', 'ba', 'bb', 'bd', 'be', 'bf', 'bg', 'bh', 'bi', 'bj', 'bm', 'bn', 'bo', 'br', 'bs', 'bt', 'bv',     'bw', 'by', 'bz', 'ca', 'cc', 'cd', 'cf', 'cg', 'ch', 'ci', 'ck', 'cl', 'cm', 'cn', 'co', 'cr', 'cu', 'cv', 'cx', 'cy',     'cz', 'de', 'dj', 'dk', 'dm', 'do', 'dz', 'ec', 'ee', 'eg', 'eh', 'er', 'es', 'et', 'eu', 'fi', 'fj', 'fk', 'fm', 'fo',     'fr', 'ga', 'gd', 'ge', 'gf', 'gg', 'gh', 'gi', 'gl', 'gm', 'gn', 'gp', 'gq', 'gr', 'gs', 'gt', 'gu', 'gw', 'gy', 'hk',     'hm', 'hn', 'hr', 'ht', 'hu', 'id', 'ie', 'il', 'im', 'in', 'io', 'iq', 'ir', 'is', 'it', 'je', 'jm', 'jo', 'jp', 'ke',     'kg', 'kh', 'ki', 'km', 'kn', 'kp', 'kr', 'kw', 'ky', 'kz', 'la', 'lb', 'lc', 'li', 'lk', 'lr', 'ls', 'lt', 'lu', 'lv',     'ly', 'ma', 'mc', 'md', 'mg', 'mh', 'mk', 'ml', 'mm', 'mn', 'mo', 'mp', 'mq', 'mr', 'ms', 'mt', 'mu', 'mv', 'mw', 'mx',     'my', 'mz', 'na', 'nc', 'ne', 'nf', 'ng', 'ni', 'nl', 'no', 'np', 'nr', 'nu', 'nz', 'om', 'pa', 'pe', 'pf', 'pg', 'ph',     'pk', 'pl', 'pm', 'pn', 'pr', 'ps', 'pt', 'pw', 'py', 'qa', 're', 'ro', 'ru', 'rw', 'sa', 'sb', 'sc', 'sd', 'se', 'sg',     'sh', 'si', 'sj', 'sk', 'sl', 'sm', 'sn', 'so', 'sr', 'st', 'sv', 'sy', 'sz', 'tc', 'td', 'tf', 'tg', 'th', 'tj', 'tk',     'tl', 'tm', 'tn', 'to', 'tp', 'tr', 'tt', 'tv', 'tw', 'tz', 'ua', 'ug', 'uk', 'um', 'us', 'uy', 'uz', 'va', 'vc', 've',     'vg', 'vi', 'vn', 'vu', 'wf', 'ws', 'ye', 'yt', 'yu', 'yr', 'za', 'zm', 'zw');

function get_domain($url){
   global $fix;
   $host =  parse_url($url,PHP_URL_HOST);
   $list = explode('.',$host);
   $res = array();
   $i = count($list) - 1;
   while($i >= 0){ 
      if(!in_array($list[$i],$fix)){
         $res[] = $list[$i];
         break;
      }   
    $res[] = $list[$i];
    $i--;
     }   
    return implode('.',array_reverse($res));
}

答案 3 :(得分:0)

您可以使用正则表达式和任何内部函数,但在复杂的域区域(.co.uk,.a.bg,.fuso.aichi.jp等)上永远不会得到正确的结果。

您需要使用使用Public Suffix List的库来进行正确的提取。我推荐TLDExtract

以下是示例代码:

$extract = new LayerShifter\TLDExtract\Extract();

$result = $extract->parse('mydomain.co.in');
$result->getSubdomain(); // will return null
$result->getHostname(); // will return 'mydomain'
$result->getSuffix(); // will return 'co.in'
$result->getFullHost(); // will return 'mydomain.co.in'
$result->getRegistrableDomain(); // will return 'mydomain.co.in'