Perl从电子邮件地址中提取域名,但不包括子域名

时间:2013-08-07 04:52:07

标签: regex perl subdomain tld

我正在努力做标题所说的,我已经得到了这个:

sub getDomain {

    my $scalarRef = shift;
    my @from_domain = split(/\@/,$$scalarRef);

    if($from_domain[1] =~ m/^.*?(\w+\.\w+)$/){
       print "$from_domain[1] $1" if($username eq 'xxx');
       return $1;
    }
}

返回domain.com的user@domain.com正常工作,但当然domain.co.uk将返回.co.uk,我需要domain.co.uk。关于如何继续这个的任何建议,我猜一个模块和一些建议某种tld查找表。

2 个答案:

答案 0 :(得分:8)

不要使用RegExp。

use Email::Address;
my ($addr) = Email::Address->parse('foo@domain.co.uk');
print "Domain: ".$addr->host."\n";
print "User:   ".$addr->user."\n";

打印:

Domain: domain.co.uk
User:   foo

答案 1 :(得分:2)

我觉得你在这里运气不好。 Net::Domain::TLD会为您提供TLD列表,但实际上并不是您想要的。

根据我的理解,给定一个像user@sub.domain.com这样的电子邮件地址,你想获得domain.com。这里的TLD是“com”,你想要TLD和它之前的域的部分。这很容易。

然后是user@sub.domain.co.uk。 TLD在这里是“英国”。但是在这里你不需要TLD和它之前的域名部分 - 你想在TLD之前有两个部分。

所以也许你需要一种启发式方法。如果TLD长度为三个字母,请使用域的上一部分,如果TLD长度为三个字母,则采用前两个部分。

但这也不起作用。并非所有ccTLD都定义了像.uk那样的子域名。以受欢迎的.tv ccTLD为例。它们允许您直接在ccTLD下注册域名。

因此,您不仅需要TLD列表。您还需要了解每个TLD适用于注册的规则。他们可能会随着时间而改变。并且正在引入新的TLD - 您需要跟上所有这些。

哦,还有最后一点。即使像.uk这样的大型ccTLD也不一定遵守自己的规则。有一些.uk域名没有顶级子域名 - .british-library。例如。

您可能能够为您特别感兴趣的域子集实现此功能。但完整的解决方案将非常复杂,几乎不可能保持最新。