我正在尝试制作一个Bash脚本来检查电子邮件地址是否正确。
我有这个正则表达式:
[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?
来源:http://www.regular-expressions.info/email.html
这是我的bash脚本:
regex=[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?
i="test@terra.es"
if [[ $i=~$regex ]] ; then
echo "OK"
else
echo "not OK"
fi
脚本失败并给我输出结果:
10:语法错误:反引号替换中的EOF
任何线索??
答案 0 :(得分:9)
这里有几个问题:
^
和$
)。?:
不受支持,需要删除。=~
运营商周围的空格。最终产品:
regex="^[a-z0-9!#\$%&'*+/=?^_\`{|}~-]+(\.[a-z0-9!#$%&'*+/=?^_\`{|}~-]+)*@([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)+[a-z0-9]([a-z0-9-]*[a-z0-9])?\$"
i="test@terra.es"
if [[ $i =~ $regex ]] ; then
echo "OK"
else
echo "not OK"
fi
答案 1 :(得分:7)
您无需创建如此复杂的正则表达式来检查有效的电子邮件。您可以简单地拆分“@”,然后检查是否有2个项目,一个位于@前面,另一个位于后面。
i="test@terraes"
IFS="@"
set -- $i
if [ "${#@}" -ne 2 ];then
echo "invalid email"
fi
domain="$2"
dig $domain | grep "ANSWER: 0" 1>/dev/null && echo "domain not ok"
要进一步检查域,您可以使用dig之类的工具来查询域。它比正则表达式更好,因为@ new.jersey与正则表达式相匹配,但它实际上不是一个合适的域。
答案 2 :(得分:5)
引号,反引号等是shell脚本中的特殊字符,如果像regex
一样使用它们,则需要进行转义。您可以使用反斜杠转义特殊字符,或者如果省略其中使用的单引号,则在正则表达式周围使用单引号。
我建议使用更简单的正则表达式,如.*@.*
,因为所有复杂性都是徒劳的。 <{1}}看起来非常精细,任何正则表达式都会接受它,但它仍然不存在。
答案 3 :(得分:1)
Bash版本低于3.2:
if [[ "$email" =~ "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$" ]]
then
echo "Email address $email is valid."
else
echo "Email address $email is invalid."
fi
Bash version greater than or equal to 3.2:
if [[ "$email" =~ ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$ ]]
then
echo "Email address $email is valid."
else
echo "Email address $email is invalid."
fi
{@ 3}}解释了您不应该使用非常具体的正则表达式的原因here。
答案 4 :(得分:0)
您的脚本存在的问题是您需要修复引号:
regex='[a-z0-9!#$%&'"'"'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'"'"'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?'
但是,此正则表达式不接受所有语法上有效的电子邮件地址。即使它确实如此,也不是所有语法上有效的电子邮件地址都可以交付。
如果可交付地址是您关心的,那么请不要使用正则表达式或其他检查语法的方法:向用户提供的地址发送质询。 注意不要在命令调用中使用不受信任的输入!使用sendmail,运行sendmail -oi -t
并将消息写入sendmail进程的标准输入,例如,
To: test@terra.es.invalid From: no-reply@your.organization.invalid Subject: email address confirmation To confirm your address, please visit the following link: http://www.your.organization.invalid/verify/1a456fadef213443
答案 5 :(得分:0)
在一次疯狂的时刻,我根据Mastering Regular Expressions书写了这个Perl子程序:
sub getRFC822AddressSpec
{
my ($esc, $space, $tab, $period) = ('\\\\', '\040', '\t', '\.');
my ($lBr, $rBr, $lPa, $rPa) = ('\[', '\]', '\(', '\)');
my ($nonAscii, $ctrl, $CRlist) = ('\200-\377', '\000-\037', '\n\015');
my $qtext = qq{ [^$esc$nonAscii$CRlist] }; # within "..."
my $dtext = qq{ [^$esc$nonAscii$CRlist$lBr$rBr] }; # within [...]
my $ctext = qq{ [^$esc$nonAscii$CRlist()] }; # within (...)
my $quoted_pair = qq{ $esc [^$nonAscii] }; # an escaped char
my $atom_char = qq{ [^()$space<>\@,;:".$esc$lBr$rBr$ctrl$nonAscii] };
my $atom = qq{ $atom_char+ # some atom chars
(?!$atom_char) # NOT followed by part of an atom
};
# rfc822 comments are (enclosed (in parentheses) like this)
my $cNested = qq{ $lPa (?: $ctext | $quoted_pair )* $rPa };
my $comment = qq{ $lPa (?: $ctext | $quoted_pair | $cNested )* $rPa };
# whitespace and comments may be scattered liberally
my $X = qq{ (?: [$space$tab] | $comment )* };
my $quoted_str = qq{ " (?: $qtext | $quoted_pair )* " };
my $word = qq{ (?: $atom | $quoted_str ) };
my $domain_ref = $atom;
my $domain_lit = qq{ $lBr (?: $dtext | $quoted_pair )* $rBr };
my $sub_domain = qq{ (?: $domain_ref | $domain_lit ) };
my $domain = qq{ $sub_domain (?: $X $period $X $sub_domain )* };
my $local_part = qq{ $word (?: $X $period $X $word )* };
my $addr_spec = qq{ $local_part $X \@ $X $domain };
# return a regular expression object
return qr{$addr_spec}ox;
}
my $spec = getRFC822AddressSpec();
my $address = q{foo (Mr. John Foo) @ bar. example};
print "$address is an email address" if ($address =~ qr{$spec});
答案 6 :(得分:0)
我已经调整了上面的示例,使其具有一个独特的函数,该函数将使用regexp检查地址的有效性,如果域实际存在dig,否则返回错误。
#!/bin/bash
#Regexp
regex="^[a-z0-9!#\$%&'*+/=?^_\`{|}~-]+(\.[a-z0-9!#$%&'*+/=?^_\`{|}~-]+)*@([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)+[a-z0-9]([a-z0-9-]*[a-z0-9])?\$"
#Vars
checkdig=0;
checkreg=0;
address=$1;
maildomain=`echo $address | awk 'BEGIN { FS = "@" } ; { print $2 }'`;
#Domain Check
checkdns() {
echo $maildomain | awk 'BEGIN { FS = "@" } ; { print $2 }' | xargs dig $maildomain | grep "ANSWER: 0" 1>/dev/null || checkdig=1;
}
#Regexp
checkreg() {
if [[ $address =~ $regex ]] ;
then checkreg=1;
fi
}
#Execute
checkreg;
checkdns;
#Results
if [ $checkreg == 1 ] && [ $checkdig == 1 ];
then echo "OK";
else echo "not OK";
fi
#End
没什么特别的。
答案 7 :(得分:0)
为聚会迟到了,但我改编了一个脚本来阅读包含电子邮件的文件,并使用RFC822正则表达式,域名拼写列表,mx查找(感谢eagle1)和不明确的电子邮件过滤来过滤它。
该脚本可以像:
一样使用./emailCheck.sh /path/to/emailList
并生成两个文件,即筛选列表和不明确的列表。两者都已从非RFC822兼容地址,没有有效MX域的电子邮件域以及域拼写错误中清除。
脚本可以在这里找到:https://github.com/deajan/linuxscripts
欢迎更正和评论:)