1

我正在尝试做标题所说的事情,我得到了这个:

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 查找表。

4

2 回答 2

8

不要使用正则表达式。

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
于 2013-08-07T05:00:54.030 回答
2

我认为你在这里不走运。Net::Domain::TLD将为您提供 TLD 列表,但这实际上并不是您想要的。

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

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

所以也许你需要一个启发式。如果 TLD 是三个字母长,取域名的前一部分,如果 TLD 是三个字母,取前两部分。

但这也行不通。并非所有 ccTLD 都像 .uk 那样定义了子域。以流行的 .tv ccTLD 为例。它们允许您直接在 ccTLD 下注册域。

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

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

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

于 2013-08-07T09:56:59.823 回答