Perl正则表达式用于具有多个TLD的电子邮件

时间:2019-02-07 21:16:49

标签: regex perl

我有一个正则表达式,只能在@符号前后匹配字母数字字符“。”和“ _”。它只能匹配以下TLD:

com,org,edu,gov,uk,net,ca,de,jp,fr,au,us,ru,ch,it,nl,se,no,mil,biz,io,cc,co,info

例如,它应该匹配sample22_test.tester.edu@auto.gmail.miltest@gmail.com,但不能匹配anothertest.325-2352@yahoo.pys(包含连字符和不匹配的TLD)或tester1234@yahoo.neta(。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之后的字符。

输入:

sample@gmail.com example@autotest.comcast.net<sender: apache.apache_testapache@apache.edu >
whoisthis@questions.gov,find@find.co{}Failure@pastattempts.frz;
sample2@yahoo.com
sample5@test.biz : test
sample92.sdfj@gmail.com
sample22_242@tech.org
greenjeans_93_who.ask@tester.info
computergeek324@ask.nets
anothertest.tester.gov@gmail.ch
helloooooow232@aol.com<;Senderfailure>
finaltest23_3test@yahoo.its

输出(我插入了注释以指示正确匹配的内容,以及不应该匹配但仍然正确的内容):

sample@gmail.com #correct
example@autotest.comcast.net #correct
apache.apache_testapache@apache.edu #should not match
whoisthis@questions.gov #correct
find@find.co #correct
Failure@past.attempts.fr #should not match
sample2@yahoo.com #correct
sample5@test.biz #correct
sample92.sdfj@gmail.com #correct
sample22_242@tech.org #correct 
greenjeans_93_who.ask@tester.info #correct
computergeek324@ask.net #should not match
anothertest.tester.gov@gmail.ch #correct
helloooooow232@aol.com #correct
finaltest23_3test@yahoo.it #should not match

编辑:电子邮件中的输入文件中包含许多其他字符,例如< , > , :, ;, ",这些字符仍然可以并且仍然可以匹配,只是不包含在上面的输出中。

1 个答案:

答案 0 :(得分:3)

由于您尝试在较大的字符串中查找这些字符,因此需要定义哪些字符不被视为电子邮件地址的一部分(我会假设您未指定的任何字符都被允许),以便您可以锚定每场比赛的开始和结束。正则表达式将继续尝试各种可能性,直到找到匹配的子字符串为止,因此,除非您定义这些约束,否则最终将在您认为与规则匹配的“电子邮件”中占据最大的块。一种方法是提取允许的所有可能的字符串,然后运行第二个正则表达式(您的原始正则表达式),并以\A\z开头和结尾,以验证其格式和TLD您想允许。

还要注意,由于TLD不区分大小写,因此您可能希望使用/i regex修饰符。

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
}