多年来,我慢慢地开发了一个正则表达式,它可以正确验证大多数电子邮件地址,假设它们不使用IP地址作为服务器部分。
我在几个PHP程序中使用它,而且大多数时候都可以使用。然而,不时有人与我联系,他们对使用它的网站有问题,我最终不得不做出一些调整(最近我意识到我不允许四个字符的TLD)。
你有或见过验证电子邮件的最佳正则表达式是什么?
我见过几种使用函数的解决方案,这些函数使用了几个较短的表达式,但我宁愿在简单函数中使用一个长的复杂表达式,而不是在更复杂的函数中使用几个短表达式。
多年来,我慢慢地开发了一个正则表达式,它可以正确验证大多数电子邮件地址,假设它们不使用IP地址作为服务器部分。
我在几个PHP程序中使用它,而且大多数时候都可以使用。然而,不时有人与我联系,他们对使用它的网站有问题,我最终不得不做出一些调整(最近我意识到我不允许四个字符的TLD)。
你有或见过验证电子邮件的最佳正则表达式是什么?
我见过几种使用函数的解决方案,这些函数使用了几个较短的表达式,但我宁愿在简单函数中使用一个长的复杂表达式,而不是在更复杂的函数中使用几个短表达式。
当前回答
对我来说,检查电子邮件地址的正确方法是:
检查符号@是否存在,在它之前和之后是否有一些非@符号:/^[^@]+@[^@]+$/尝试用一些“激活码”向该地址发送电子邮件。当用户“激活”他/她的电子邮件地址时,我们将看到一切都是正确的。
当然,当用户键入一封“奇怪”的电子邮件时,您可以在前端显示一些警告或提示,以帮助他/她避免常见错误,如域名部分没有圆点或名称中没有空格而没有引号等。但您必须接受地址“hello@world“如果用户真的想要它。
此外,您必须记住,电子邮件地址标准过去和将来都会发展,因此您不能总是只键入一些“标准有效”的正则表达式。而且你必须记住,一些具体的互联网服务器可能会在一些常见标准的细节上失败,事实上,它们可以使用自己的“修改标准”。
所以,只需检查@,在前端提示用户,并在给定地址发送验证电子邮件。
其他回答
电子邮件正则表达式(RFC 5322)
(?im)^(?=.{1,64}@)(?:("[^"\\]*(?:\\.[^"\\]*)*"@)|((?:[0-9a-z](?:\.(?!\.)|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)?[0-9a-z]@))(?=.{1,255}$)(?:(\[(?:\d{1,3}\.){3}\d{1,3}\])|((?:(?=.{1,63}\.)[0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9])|((?=.{1,63}$)[0-9a-z][-\w]*))$
演示https://regex101.com/r/ObS3QZ/1
# (?im)^(?=.{1,64}@)(?:("[^"\\]*(?:\\.[^"\\]*)*"@)|((?:[0-9a-z](?:\.(?!\.)|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)?[0-9a-z]@))(?=.{1,255}$)(?:(\[(?:\d{1,3}\.){3}\d{1,3}\])|((?:(?=.{1,63}\.)[0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9])|((?=.{1,63}$)[0-9a-z][-\w]*))$
# Note - remove all comments '(comments)' before running this regex
# Find \([^)]*\) replace with nothing
(?im) # Case insensitive
^ # BOS
# Local part
(?= .{1,64} @ ) # 64 max chars
(?:
( # (1 start), Quoted
" [^"\\]*
(?: \\ . [^"\\]* )*
"
@
) # (1 end)
| # or,
( # (2 start), Non-quoted
(?:
[0-9a-z]
(?:
\.
(?! \. )
| # or,
[-!#\$%&'\*\+/=\?\^`\{\}\|~\w]
)*
)?
[0-9a-z]
@
) # (2 end)
)
# Domain part
(?= .{1,255} $ ) # 255 max chars
(?:
( # (3 start), IP
\[
(?: \d{1,3} \. ){3}
\d{1,3} \]
) # (3 end)
| # or,
( # (4 start), Others
(?: # Labels (63 max chars each)
(?= .{1,63} \. )
[0-9a-z] [-\w]* [0-9a-z]*
\.
)+
[a-z0-9] [\-a-z0-9]{0,22} [a-z0-9]
) # (4 end)
| # or,
( # (5 start), Localdomain
(?= .{1,63} $ )
[0-9a-z] [-\w]*
) # (5 end)
)
$ # EOS
这是电子邮件的正则表达式之一:
^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$
我从不麻烦用自己的正则表达式创建,因为很可能其他人已经提出了更好的版本。我总是使用regexlib来找到一个我喜欢的。
自2010年5月以来,互联网上存在非拉丁语(中文、阿拉伯文、希腊文、希伯来文、西里尔文等)域名。每个人都必须更改使用的电子邮件正则表达式,因为这些字符肯定不会被[a-z]/i或\w覆盖。他们都会失败。
毕竟,验证电子邮件地址的最佳方法仍然是向有问题的地址发送电子邮件以验证地址。如果电子邮件地址是用户身份验证(注册/登录等)的一部分,那么您可以将其与用户激活系统完美结合。即,发送带有指向指定电子邮件地址的唯一激活密钥的链接的电子邮件,并且仅当用户使用电子邮件中的链接激活了新创建的帐户时才允许登录。
如果正则表达式的目的只是在UI中快速通知用户指定的电子邮件地址格式不正确,那么最好还是检查它是否与以下正则表达式基本匹配:
^([^.@]+)(\.[^.@]+)*@([^.@]+\.)+([^.@]+)$
就这么简单。你到底为什么会在意名字和域名中使用的字符?输入有效的电子邮件地址是客户的责任,而不是服务器的。即使客户端输入语法上有效的电子邮件地址,如aa@bb.cc,这不能保证它是合法的电子邮件地址。没有一个正则表达式可以涵盖这一点。
这一切都取决于你想要的准确度。出于我的目的,我只是想避开bob@aol.com(电子邮件中的空格)或steve(完全没有域名)或mary@aolcom(在.com之前没有句点),我使用
/^\S+@\S+\.\S+$/
当然,它会匹配不是有效电子邮件地址的内容,但这是一个常见的简单错误问题。
可以对该正则表达式进行任意数量的更改(其中一些在这个答案的注释中),但它很简单,易于理解,是一个很好的第一次尝试。