Perl的正则表达式与多个TLD电子邮件

问题描述 投票:1回答:1

我有一个正则表达式那就是只匹配字母数字字符,“”和“_”之前和@符号后。它是只匹配以下顶级域名:

COM,组织,EDU,GOV,英国,净,CA,德,日本,法国,澳大利亚,美国,RU,CH,IT,NL,SE,不,MIL,商务,IO,CC,CO,资讯

例如,它应该匹配[email protected][email protected],但不是[email protected](包含连字符和不匹配TLD)或[email protected](.NET是匹配TLD,但.neta不是)

我有以下的正则表达式:

my $email_regex = qr/[a-zA-Z0-9._]+\@[a-zA-Z0-9._]+\.(com|org|edu|gov|uk|net|ca|de|jp|fr|au|us|ru|ch|it|nl|se|no|mil|biz|io|cc|co|info)/;

这是正确地匹配到适当的TLD,但这时如果TLD具有后它的任何附加的字母数字字符,但仍在计数它作为一个匹配(它不应该),它只是不显示后的任何字母数字字符TLD。

输入:

[email protected] [email protected]<sender: [email protected] >
[email protected],[email protected]{}[email protected];
[email protected]
[email protected] : test
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]<;Senderfailure>
[email protected]

输出(I已插入注释指示正确匹配,什么不应该匹配,但反正一样):

[email protected] #correct
[email protected] #correct
[email protected] #should not match
[email protected] #correct
[email protected] #correct
[email protected] #should not match
[email protected] #correct
[email protected] #correct
[email protected] #correct
[email protected] #correct 
[email protected] #correct
[email protected] #should not match
[email protected] #correct
[email protected] #correct
[email protected] #should not match

编辑:输入文件包含电子邮件后许多其他字符,如< , > , :, ;, "这些都是可以的,仍然可以匹配的,只是没有包含在输出由上述可见。

regex perl
1个回答
3
投票

既然你正在尝试一个较大的字符串中找到这些,你需要定义什么字符就不会被认为是电子邮件地址的一部分(我会假设你没有指定所允许的任何字符),这样就可以锚开始和结束的每场比赛。正则表达式将继续努力,每一种可能性,直到他们找到匹配,所以除非你定义这些约束,你最终会与您认为什么是“电子邮件”匹配您的规则,最大的块的子字符串。一种方法是提取你允许所有可能的字符的字符串,然后运行第二个正则表达式(你原来的正则表达式),挂靠在开始与\A\z结束,以验证您要允许其格式和顶级域名。

还要注意,由于顶级域名不区分大小写,您可能希望/i正则表达式修改。

foreach my $email ($str =~ m/([a-zA-Z0-9._@]+)/g) {
    next unless $email =~ m/\A...\z/i;
}

您正则表达式也远远不完整,电子邮件地址是复杂的。 (如果你想看到什么完整的电子邮件地址的解析正则表达式的样子,check out Email::Valid。)如果您希望让更多有效的电子邮件地址,并在你的方法灵活,我建议使用Email::Address::XS解析他们。

use strict;
use warnings;
use Email::Address::XS;

my $tld_re = qr/\.(com|org|edu|gov|uk|net|ca|de|jp|fr|au|us|ru|ch|it|nl|se|no|mil|biz|io|cc|co|info)\z/i;

my $address = Email::Address::XS->parse_bare_address($email);

if ($address->is_valid and $address->host =~ m/$tld_re/) {
   # matches
}
© www.soinside.com 2019 - 2024. All rights reserved.