允许+正则表达式电子邮件验证电子邮件

时间:2011-03-31 16:33:51

标签: php regex preg-match

正则表达式让我大吃一惊。如何更改此选项以验证带加号的电子邮件?所以我可以用test+spam@gmail.com注册。

if(!preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*$/i", $_GET['em'])) {

6 个答案:

答案 0 :(得分:33)

您似乎并不熟悉当前正则表达式所做的事情,这在修改它之前是一个很好的第一步。让我们使用电子邮件地址john.robert.smith@mail.com遍历您的正则表达式(在下面的每个部分中,粗体部分是该部分匹配的内容):

  1. ^start of string anchor。 它指定任何匹配必须 从一开始就开始了 串。如果模式不是 锚定,正则表达式引擎可以匹配 一个子串,通常是 不希望的。

    锚点是零宽度,意思是 他们没有抓住任何角色。

  2. [_a-z0-9-]+由两个人组成 元素,character classrepetition modifer

    • [...]定义一个字符类,它告诉正则表达式引擎, 这些字符中的任何一个都是有效的匹配。在这种情况下的类 包含字符a-z,数字 0-9和短划线和下划线(in 一般来说,一个字符类中的破折号 定义范围,以便您可以使用 a-z代替 abcdefghijklmnopqrstuvwxyz;什么时候 作为最后一个角色给出 class,它充当文字破折号。)
    • +是一个重复修饰符,指定前面的标记 (在这种情况下,字符类) 可以重复一次或多次。 还有另外两个重复 运算符:*匹配零或更多 倍; ?完全匹配为零或 一次(即制造一些东西 可选的的)。

    (捕获 的约翰 .robert.smith @ mail.com)

  3. (\.[_a-z0-9-]+)*再次包含一个 重复的人物类。它也是 包含一个 group, 和逃脱的角色:

    • (...)定义了一个组,允许您对多个令牌进行分组 在一起(在这种情况下,该组 将作为一个重复 整个)。
      我们说我们想要 匹配'abc',零次或多次(即。 abcabcabc匹配,abcccc没有)。 如果我们试图使用该模式 abc*,重复修饰符 只适用于c,因为 c是之前的最后一个标记 修改。为了到处走走 这个,我们可以分组abc((abc)*), 在这种情况下,修饰符会 适用于整个集团,就好像它一样 是一个单一的标记。
    • \.指定一个文字点字符。这是需要的原因 是因为.是一个特殊的 正则表达式中的字符,意思是any character。 因为我们想匹配一个实际的点 我们需要逃脱它。

    (捕获 约翰的 .robert.smith @ mail.com)

  4. @不是特殊字符 正则表达式,所以,像其他所有 非特殊字符,匹配 从字面上。
    (捕获john.robert.smith @ mail.com)

  5. [a-z0-9-]+再次定义了重复的字符类,如上面的第2项。
    (捕获john.robert.smith @ mail .com)

  6. (\.[a-z0-9-]+)*与上面的#3几乎完全相同。
    (捕获john.robert.smith@mail .com

  7. $是字符串锚点的结尾。它的作用与上面的^相同,除了匹配字符串的结尾。


  8. 考虑到这一点,如何添加捕获加段的部分应该更清楚一点。如上所述,+是一个特殊字符,因此必须进行转义。然后,由于+必须跟随一些字符,我们可以定义一个包含我们想要匹配的字符的字符类并定义它的重复。最后,我们应该将整个组设为可选,因为电子邮件地址不需要+段:

    (\+[a-z0-9-]+)?
    

    当插入你的正则表达式时,它看起来像这样:

    /^[_a-z0-9-]+(\.[_a-z0-9-]+)*(\+[a-z0-9-]+)?@[a-z0-9-]+(\.[a-z0-9-]+)*$/i
    

答案 1 :(得分:7)

拯救你的理智。获取预制的PHP RFC 822 Email address parser

答案 2 :(得分:1)

我已使用this regex来验证电子邮件,它适用于包含+的电子邮件:

/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/

答案 3 :(得分:1)

\+将匹配文字+符号,但要注意:根据RFC规范,您仍然不会接近匹配所有可能的电子邮件地址,因为the actual regex for that is madness。这几乎肯定不值得;你应该使用真正的电子邮件解析器。

答案 4 :(得分:0)

这是另一种解决方案(类似于David发现的解决方案):

//Escaped for .Net
^[_a-zA-Z0-9-]+((\\.[_a-zA-Z0-9-]+)*|(\\+[_a-zA-Z0-9-]+)*)*@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*(\\.[a-zA-Z]{2,4})$

//Native
^[_a-zA-Z0-9-]+((\.[_a-zA-Z0-9-]+)*|(\+[_a-zA-Z0-9-]+)*)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*(\.[a-zA-Z]{2,4})$

答案 5 :(得分:0)

这是另一种解决方案

/^[_a-z0-9-+]+(\.[_a-z0-9-+]+)*(\+[a-z0-9-]+)?@[a-z0-9-.]+(\.[a-z0-9]+)$/

or For razor page(@=\u0040)

/^[_a-z0-9-+]+(\.[_a-z0-9-+]+)*(\+[a-z0-9-]+)?\u0040[a-z0-9-.]+(\.[a-z0-9]+)$/