在Perl中用于拆分电子邮件的正则表达式

3

我的同事问我如何查找最后一个出现的不止一个@符号@。

示例:

j@ssi@aliencoders.com@..coding.com

所以它应该显示j@ssi@aliencoders.com作为用户名和..coding.com作为域名。在Perl中有没有一行正则表达式可以得到所需的输出?
5个回答

8
my ($username, $domain) = $str =~ /(.*)@(.*)/;

更多信息请参见perlre

默认情况下,量化子模式是“贪婪”的,也就是说,它会尽可能地匹配多次(在特定的起始位置),同时仍然允许其余部分匹配。


6

只需使用贪心算法:

/(.*)@(.*)$/

第一部分会尽可能地获取内容,直到遇到 @ 符号。最后一部分则会获取从 @ 符号后一直到行末的所有内容。


它有多高效?我写了同样的东西,但我正在寻找任何更好的解决方案,可以从文件中过滤出每个这样的邮件地址。感谢Koneark提供的正则表达式 :) - Jassi
1
“它有多高效”唯一真正的答案是“基准测试”,但编译像那样简单的正则表达式不应该是问题。Perl 实际上是为正则表达式而生的。如果您认为其他解决方案(也许是 index+substring?也许是 split?)可能更快,请对它们进行基准测试:] - Konerak

2
$str='j@ssi@aliencoders.com@..coding.com';
$user=qw();
$domain=qw();
while($str=~m/\@/g){
    $user=$`;
    $domain=$';
}
print "user -> $user\n";
print "domain->$domain\n";

为什么麻烦初始化 $user$domain 变量? - Nathan Fellman
谢谢。如果您同时使用strict和warnings模块,需要初始化以确保没有任何错误或警告。 - Jassi

2
Perl中的量词默认情况下是贪婪的。这意味着它们会尽可能地匹配更多内容。
您需要的是一个简单的:
($username, $domain) = ($string =~ /(.*)@(.*)$/);

如果您想100%确定第二部分没有@,您可以使用:
($username, $domain) = ($string =~ /(.*)@([^@]*)$/);

1
最后一行有多余的内容。使用贪婪搜索,我认为它没有任何用处...所以你的第一段代码和第二段代码具有相同的效果。谢谢。 - Jassi

1
使用Email::Address。这些事情对于简单的正则表达式来说太难了,很容易出错。哎呀,没有仔细读op,但是这段代码适用于拆分电子邮件地址。
use strict;
use warnings;
use Email::Address;

my $line = 'bill@example.com;joe@example.com';
my @addresses = Email::Address->parse($line);
for my $address (@addresses) {
  print $address->format, "\n";
}

在使用它之前,需要安装Email::Address。默认情况下它不会存在。否则,它是一个非常酷的模块,适用于所有电子邮件验证工作。 - Jassi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接