我有一个正则表达式,只能在@符号前后匹配字母数字字符“。”和“ _”。它只能匹配以下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.mil
和test@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
编辑:电子邮件中的输入文件中包含许多其他字符,例如< , > , :, ;, "
,这些字符仍然可以并且仍然可以匹配,只是不包含在上面的输出中。
答案 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
}