【问题标题】:Perl Regex E-Mail TLDPerl 正则表达式电子邮件 TLD
【发布时间】:2015-11-08 20:36:36
【问题描述】:

我有这个代码:

    if ( $Mail =~ /$Tld{$_}/ ) {
        $TldFound = 1;      
    }

变量 $Mail 具有例如信息“mail@mail.com”。变量 $Tld 具有信息“.com”。我怎样才能削减只有 tld .com 将保留的变量 $Mail?

【问题讨论】:

  • 除了缺乏 Perl 知识之外,您没有具体问题。您不应该依靠 Stack Overflow 上人们的好意来逐步学习该语言,我相信您需要的是 Perl tutorial
  • 你可以用@.*\.(.*)做一个hacky解决方案这会将最后一个.之后的所有内容存储到$1\1中。但是,对于外国域,这不起作用,或者您还想要我怀疑的二级域(例如 co.uk)。

标签: regex perl email tld


【解决方案1】:

您应该使用Email::Address 来解析电子邮件地址。

为了能够确定地提取 TLD,需要一份您认为是 TLD 的列表。例如,.co.uk.com.tr 算不算?或者,您只想要最后一串非点字符?

如果您将注意力限制在 2 到 3 个字符的 TLD,例如 .co.com.io.net.org.us 等,您可以使用 my ($tld) = ($email =~ /[.] ([a-z]{2,3}) \z/x); 然后检查if ($tld and ($tld eq 'com')) { ... } 等,但您确实想要一份可以作为 TLD 的可接受字符串的良好列表:Net::Domain::TLDMozilla::PublicSuffix

【讨论】:

  • 虽然我同意你的第一句话,但你的回答创造了原始问题不需要的不必要的复杂性。您的方法需要一份详尽的 TLD 列表,这对于这个特定问题来说太过分了。
  • 我发现,当人们说“不需要”时,他们最终会在周末和假期里扑灭后来引起的火灾。您不需要一份详尽的清单:只需一份足以解决问题的全面清单。即使那样,那是什么?五分钟的谷歌搜索?
【解决方案2】:

朴素的正则表达式解决方案

以下解决方案将解决您发布的问题,但并非旨在解决所有可能的极端情况。全面解析电子邮件地址并非易事,如果您想处理 RFC 的全部复杂性,则需要一个解析器,例如 Email::Address

从字符串打印您的 TLD

由于您已经知道要在成功时打印的字符串(例如“.com”),因此您实际上并不需要正则表达式匹配的 result;当匹配为真时,您可以使用语句后条件打印存储在 $Tld 中的字符串。例如:

$Mail = 'mail@mail.com';
$Tld  = '.com';

print "$Tld\n" if $Mail =~ /${Tld}$/;

这将正确打印:

.com

打印比赛

如果您真的想要完整匹配,有很多方法可以做到。一种方法是使用特殊的 $& 变量:

$Mail = 'mail@mail.com';
$Tld  = '.com';

if ($Mail =~ /${Tld}$/) {
    print "$&\n";
}

这也将正确打印:

.com

对字符串进行分区

前面的所有示例都将解决您发布的问题,但没有解析器的最佳通用解决方案实际上是对 TLD 进行分区,并将域的最后一段视为未经验证的 TLD . Ruby 有超级方便的String#rpartition 方法,但我不知道 Perl 中有类似的函数。但是,您可以使用锚定匹配来完成几乎相同的事情。例如:

$Mail = 'mail@mail.com';

$Mail =~ /(\.[[:alpha:]]+)$/;
print "$1\n";

如果您需要根据 .com 等预期值验证 TLD,您可以将其与字符串或变量进行比较。例如:

$Mail = 'mail@mail.com';
$Tld  = '.com';

$Mail =~ /(\.[[:alpha:]]+)$/;
print "$1\n" if $1 eq $Tld

【讨论】:

  • 这个答案在很多方面都是错误的......首先,您认为$Mail$Mail = "mail@mail.com" 之后包含什么?其次,您是否意识到. 在正则表达式模式中很特别?第三,如果$Mail 包含acommander@example.org 怎么办?发布这样的东西有什么意义?
  • @SinanÜnür 感谢您的咆哮,并在 Stack Overflow 上公开展示您缺乏社交技能。答案有效,提供了独立的示例,并将解决 OP 的发布的问题,而不是旨在解决所有可以想象的边缘情况。但是,答案已更新为锚定正则表达式,因为我同意 /.com/ 会过于宽泛。
  • 如果$Mail".com\n" 结尾,模式匹配是否应该成功?另外,您是否意识到. 在正则表达式模式中很特别?
  • 在思南指出的问题中,我建议不要使用行尾锚$,因为它现在可以使用默认的正则表达式标志来改变行为。如果需要字符串结尾,请使用 \z
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-24
  • 2011-12-28
  • 2012-01-02
  • 2015-12-03
相关资源
最近更新 更多