正则表达式很难识别电子邮件地址?
我最近在某处读到,考虑到该标准的所有变化和可能性,编写一个正则表达式以匹配电子邮件地址非常困难,并且比最初设想的要复杂得多。
谁能提供一些关于这为什么的见解?
是否有任何已知且经过验证的正则表达式实际上可以完全做到这一点?
使用正则表达式匹配电子邮件地址有哪些好的选择?
解决方案
对于正式的电子邮件规范,是的,由于诸如注释(尤其是如果我们不首先将注释删除到空白)等各种形式的递归,以及各种不同的格式(电子邮件地址为并不总是某人@ somewhere.tld)。我们可以接近(使用一些庞大且难以理解的Regex模式),但是检查电子邮件的一种更好的方法是进行非常熟悉的握手:
- 他们告诉你他们的电子邮件
- 我们通过电子邮件向他们发送带有Guid的确认链接
- 它存在
- 他们拥有它
比盲目接受电子邮件地址要好得多。
谁能提供一些关于这是为什么的见解?
是的,这是一个极其复杂的标准,它允许许多今天没有人真正使用的东西。
:)
是否有任何已知且经过验证的正则表达式实际上可以完全做到这一点?
这是完全解析整个标准的一种尝试。
http://ex-parrot.com/~pdw/Mail-RFC822-Address.html
使用正则表达式匹配电子邮件地址有哪些好的选择?
我猜我们正在以任何一种语言使用现有框架吗?尽管那些可能会在内部使用regexp。这是一个复杂的字符串。正则表达式旨在解析复杂的字符串,因此,这实际上是最佳选择。
编辑:我应该补充一点,我链接到的正则表达式只是为了好玩。我不赞成使用复杂的正则表达式,就像有些人说的那样:"如果正则表达式多于一行,则可以保证某个地方存在错误"。我链接到它以说明该标准有多复杂。
BNF中有一个上下文无关的语法,用于描述RFC-2822中的有效电子邮件地址。这很复杂。例如:
" @ "@example.com
是有效的电子邮件地址。我不知道有什么正则表达式可以完全做到这一点;通常给出的示例要求首先删除注释。我编写了一个递归下降解析器来完全完成一次。
某些正则表达式实际上可以与嵌套括号匹配(例如,与Perl兼容的括号)。就是说,我已经看到一个正则表达式声称可以正确匹配RFC 822,并且它是两页文本,没有任何空格。因此,检测有效电子邮件地址的最佳方法是向其发送电子邮件,并查看其是否有效。
试试这个:
"(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])"
详细信息请看这里。
但是,与其实施RFC822标准,不如从另一个角度来看它会更好。如果邮件服务器不镜像标准,则标准说什么并不重要。因此,我认为最好在验证电子邮件地址时模仿最流行的邮件服务器的功能。
这确实很困难,因为根据电子邮件规范RFC 2822,在电子邮件地址中有很多东西可以有效。通常看不到的东西(例如+)是电子邮件地址的完全有效字符。规格。
在http://regexlib.com上有一整节专门讨论电子邮件地址,这是一个很好的资源。我建议我们确定哪些标准对我们很重要,然后找到一个匹配的标准。对于规范允许的所有可能性,大多数人确实并不需要全面的支持。
有许多执行此操作的Perl模块(例如)。不要尝试编写自己的正则表达式来做到这一点。看着
Mail :: VRFY将进行语法和网络检查(并且SMTP服务器在某个地方接受此地址)
https://metacpan.org/pod/Mail::VRFY
RFC :: RFC822 :: Address递归血统电子邮件地址解析器。
https://metacpan.org/pod/RFC::RFC822 ::地址
Mail :: RFC822 :: Address基于正则表达式的地址验证,值得一看的疯狂正则表达式
http://ex-parrot.com/~pdw/Mail-RFC822-Address.html
对于其他语言,也存在类似的工具。以下疯狂的正则表达式...
(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\".\[\]var_dump(filter_var('[email protected]', FILTER_VALIDATE_EMAIL));0-1]+(?:(?:(?:\r\n)?[ \t] )+|\Z|(?=[\["()<>@,;:\".\[\]]))|"(?:[^\"\r\]|\.|(?:(?:\r\n)?[ \t]))*"(?:(?: \r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\".\[\]^[a-zA-Z]([.]?([a-zA-Z0-9_-]+)*)?@([a-zA-Z0-9\-_]+\.)+[a-zA-Z]{2,4}$0-1]+(?:(?:( ?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\".\[\]]))|"(?:[^\"\r\]|\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\".\[\] ##代码##0-##代码## 31]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\".\[\]]))|\[([^\[\]\r\]|\.)*\ ](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\".\[\] ##代码##0-1]+ (?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\".\[\]]))|\[([^\[\]\r\]|\.)*\](?: (?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z |(?=[\["()<>@,;:\".\[\]]))|"(?:[^\"\r\]|\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n) ?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\ r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\".\[\]]))|\[([^\[\]\r\]|\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n) ?[ \t])+|\Z|(?=[\["()<>@,;:\".\[\]]))|\[([^\[\]\r\]|\.)*\](?:(?:\r\n)?[ \t] )*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\".\[\]]))|\[([^\[\]\r\]|\.)*\](?:(?:\r\n)?[ \t])* )(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t] )+|\Z|(?=[\["()<>@,;:\".\[\]]))|\[([^\[\]\r\]|\.)*\](?:(?:\r\n)?[ \t])*))*) *:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+ |\Z|(?=[\["()<>@,;:\".\[\]]))|"(?:[^\"\r\]|\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r \n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?: \r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\".\[\]]))|"(?:[^\"\r\]|\.|(?:(?:\r\n)?[ \t ]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\".\[\] ##代码##0-1 ]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\".\[\]]))|\[([^\[\]\r\]|\.)*\]( ?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\".\[\] ##代码##0-1]+(? :(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\".\[\]]))|\[([^\[\]\r\]|\.)*\](?:(? :\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)|(?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(? :(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\".\[\]]))|"(?:[^\"\r\]|\.|(?:(?:\r\n)? [ \t]))*"(?:(?:\r\n)?[ \t])*)*:(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\".\[\]]))|"(?:[^\"\r\]| \.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<> @,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\".\[\]]))|" (?:[^\"\r\]|\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t] )*(?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\ ".\[\]]))|\[([^\[\]\r\]|\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(? :[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\".\[ \]]))|\[([^\[\]\r\]|\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\".\[\] ##代码##0- 1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\".\[\]]))|"(?:[^\"\r\]|\.|( ?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,; :\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\".\[\]]))|\[([ ^\[\]\r\]|\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\" .\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\".\[\]]))|\[([^\[\ ]\r\]|\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\".\ [\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\".\[\]]))|\[([^\[\]\ r\]|\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\".\[\]]))|\[([^\[\]\r\] |\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\".\[\] ##代码## 00-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\".\[\]]))|"(?:[^\"\r\]|\ .|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@, ;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\".\[\]]))|"(? :[^\"\r\]|\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])* (?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\". \[\]]))|\[([^\[\]\r\]|\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[ ^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\".\[\] ]))|\[([^\[\]\r\]|\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)(?:,\s*( ?:(?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\ ".\[\]]))|"(?:[^\"\r\]|\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:( ?:\r\n)?[ \t])*(?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[ \["()<>@,;:\".\[\]]))|"(?:[^\"\r\]|\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t ])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t ])+|\Z|(?=[\["()<>@,;:\".\[\]]))|\[([^\[\]\r\]|\.)*\](?:(?:\r\n)?[ \t])*)(? :\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+| \Z|(?=[\["()<>@,;:\".\[\]]))|\[([^\[\]\r\]|\.)*\](?:(?:\r\n)?[ \t])*))*|(?: [^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\".\[\ ]]))|"(?:[^\"\r\]|\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n) ?[ \t])*(?:@(?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[" ()<>@,;:\".\[\]]))|\[([^\[\]\r\]|\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n) ?[ \t])*(?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<> @,;:\".\[\]]))|\[([^\[\]\r\]|\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@, ;:\".\[\]]))|\[([^\[\]\r\]|\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t] )*(?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\ ".\[\]]))|\[([^\[\]\r\]|\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)? (?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\". \[\]]))|"(?:[^\"\r\]|\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?: \r\n)?[ \t])*(?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[ "()<>@,;:\".\[\]]))|"(?:[^\"\r\]|\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t]) *))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t]) +|\Z|(?=[\["()<>@,;:\".\[\]]))|\[([^\[\]\r\]|\.)*\](?:(?:\r\n)?[ \t])*)(?:\ .(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\".\[\] ##代码##0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z |(?=[\["()<>@,;:\".\[\]]))|\[([^\[\]\r\]|\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:( ?:\r\n)?[ \t])*))*)?;\s*)
引用和RFC的其他很少使用但有效的部分使其变得很难。除了"很难"之外,我对这个话题还不够明确,无法发表明确的评论,但幸运的是,其他人对此进行了详尽的介绍。
对于有效的正则表达式,Perl Mail :: Rfc822 :: Address模块包含一个正则表达式,该正则表达式显然可以正常工作,但前提是已将任何注释替换为空白。 (在电子邮件地址中发表评论?我们明白了为什么它比人们想象的要难...)
当然,到处都有简化的正则表达式将验证几乎每一个真正使用的电子邮件地址。
许多人尝试了,许多人接近了。我们可能需要阅读Wikipedia文章以及其他一些文章。
具体来说,我们需要记住,许多网站和电子邮件服务器都对电子邮件地址进行了轻松的验证,因此从本质上讲它们并未完全实现该标准。足够使电子邮件始终保持工作状态。
尽管并不是所有的废话,因为允许诸如" +"之类的字符对于打击垃圾邮件的用户非常有用,例如[email protected](即时的一次性Gmail地址)。
但是只有当网站接受它时。
除了韦恩斯的答案外,还有关于电子邮件的www.regular-expressions.info上的一部分,其中有一些示例。
我们总是可以质疑这是否值得,或者实际上覆盖率不到100%的正则表达式仅会导致错误的安全感。
最后,实际发送电子邮件将提供真正的最终验证。 (-我们将发现邮件服务器是否有错误;-)
无论如何,验证电子邮件地址并不是很有帮助。它不会捕获常见的拼写错误或者伪造的电子邮件地址,因为它们在语法上往往看起来像有效地址。
如果要确保地址有效,则别无选择,只能发送确认邮件。
如果只想确保用户输入的内容类似于电子邮件,而不仅仅是" asdf",则请检查@。更复杂的验证并没有真正提供任何好处。
(我知道这不能回答问题,但是无论如何我都值得一提)
为了使本文完整,也为PHP保留了内置的语言功能,用于验证电子邮件。
对于PHP,请使用带有特定EMAIL验证类型的nice filter_var :)
在php中不再有疯狂的电子邮件正则表达式:D
##代码##http://www.php.net/filter_var
只是添加一个比@mmaibaum列出的正则表达式少疯狂的正则表达式:
##代码##它不是防弹的,当然也不能涵盖整个电子邮件规范,但是它确实可以满足大多数基本要求。更好的是,它在某种程度上可以理解,并且可以进行编辑。
来自HouseOfFusion.com(世界一流的ColdFusion资源)的讨论中的内容。
在我看来,是否接受离奇的,不常见的电子邮件地址格式取决于人们想要使用它们的方式。
如果我们正在编写邮件服务器,则必须非常准确且正确无误地接受内容。因此,上面引用的"疯狂"正则表达式是合适的。
但是,对于我们其余的人,我们主要只是想确保用户在Web表单中键入的内容看起来合理,并且其中没有某种SQL注入或者缓冲区溢出。
坦白说,在注册邮件列表,新闻稿或者网站时,是否真的有人在乎允许某人输入200个字符的电子邮件地址,其中包含注释,换行符,引号,空格,括号或者其他乱码?对这类小丑的正确回应是"当地址看起来像[email protected]时,请稍后再回来"。
我所做的验证包括确保确切存在一个" @";没有空格,空值或者换行符; '@'右边的部分至少有一个点(但连续没有两个点);并且没有引号,括号,逗号,冒号,感叹号,分号或者反斜杠,与实际电子邮件地址的一部分相比,所有这些更有可能是黑客行为。
是的,这意味着我拒绝了可能有人尝试在我的网站上注册的有效地址,或者我"错误地"拒绝了多达0.001%的真实地址!我可以忍受这一点。
在Java中检查电子邮件地址的一种简单有效的方法是使用Apache Commons Validator库的EmailValidator。
在发送电子邮件之前,我总是会检查输入表单中的电子邮件地址是否与此类似,即使我们只发现一些错字也是如此。我们可能不想为"投递失败"通知邮件编写自动扫描程序。 :-)
我现在整理了Cal Henderson,Dave Child,Phil Haack,Doug Lovell和RFC 3696的测试用例。总共有158个测试地址。
我对所有可以找到的验证器进行了所有这些测试。比较在这里:http://www.dominicsayers.com/isemail
当人们增强其验证器时,我将尝试使此页面保持最新。感谢Cal,Dave和Phil在汇编这些测试和对我自己的验证程序的建设性批评方面所提供的帮助和合作。
人们应该特别注意针对RFC 3696的勘误表。实际上,其中三个规范示例是无效地址。地址的最大长度为254或者256个字符,而不是320。
如果我们在.NET Framework上运行,则只需尝试实例化一个MailAddress对象,并炸开FormatException,如果成功则将其拉出。在不理会捕获异常的性能的情况下(确实,如果仅在单个Web表单上它就不会产生太大的变化),. NET框架中的MailAddress类经历了相当长的一段时间。完整的解析过程(不使用RegEx)。打开Reflector并搜索MailAddress
和MailBnfHelper.ReadMailAddress()
以查看它所做的所有奇特的东西。比我更聪明的人花了很多时间在Microsoft构建该解析器,当我实际向该地址发送电子邮件时,我将使用它,因此我也可能会使用它来验证传入的地址。
Java的此类在其中具有验证器:
http://www.leshazlewood.com/?p=23
这是由Shiro(以前是Ki,以前是JSecurity)的创建者写的
测试电子邮件地址有效性的利弊:
有两种用于验证电子邮件的正则表达式:
- 太松散的人。
- 太严格了。
正则表达式不可能匹配所有有效的电子邮件地址,也不能匹配无效的电子邮件地址,因为某些字符串可能看起来像有效的电子邮件地址,但实际上并没有进入任何人的收件箱。测试以查看电子邮件是否实际有效的唯一方法是将电子邮件发送到该地址,然后查看是否收到某种回复。考虑到这一点,对匹配电子邮件过于严格的正则表达式似乎并没有太大的用途。
我认为大多数要求电子邮件正则表达式的人都在寻找第一种选择,即过于宽松的正则表达式。他们想测试一个字符串,看看它是否看起来像一封电子邮件,如果绝对不是电子邮件,那么他们可以对用户说:"嘿,我们应该在这里放置一封电子邮件,这肯定是不是有效的电子邮件。也许我们没有意识到此字段是用于电子邮件的,或者可能是拼写错误"。
如果用户输入的字符串看起来很像有效的电子邮件,但实际上不是一个字符串,那么这是一个问题,应由应用程序的不同部分处理。