开发者

Allow + in regex email validate email [duplicate]

This question already has answers here: How to validate an email address in PHP (15 answers) Closed 2 years ago.

Regex is blowing my mind. How can I change开发者_运维知识库 this to validate emails with a plus sign? so I can sign up with test+spam@gmail.com

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


It seems like you aren't really familiar with what your regex is doing currently, which would be a good first step before modifying it. Let's walk through your regex using the email address john.robert.smith@mail.com (in each section below, the bolded part is what is matched by that section):

  1. ^ is the start of string anchor. It specifies that any match must begin at the beginning of the string. If the pattern is not anchored, the regex engine can match a substring, which is often undesired.

    Anchors are zero-width, meaning that they do not capture any characters.

  2. [_a-z0-9-]+ is made up of two elements, a character class and a repetition modifer:

    • [...] defines a character class, which tells the regex engine, any of these characters are valid matches. In this case the class contains the characters a-z, numbers 0-9 and the dash and underscore (in general, a dash in a character class defines a range, so you can use a-z instead of abcdefghijklmnopqrstuvwxyz; when given as the last character in the class, it acts as a literal dash).
    • + is a repetition modifier that specifies that the preceding token (in this case, the character class) can be repeated one or more times. There are two other repetition operators: * matches zero or more times; ? matches exactly zero or one times (ie. makes something optional).

    (captures john.robert.smith@mail.com)

  3. (\.[_a-z0-9-]+)* again contains a repeated character class. It also contains a group, and an escaped character:

    • (...) defines a group, which allows you to group multiple tokens together (in this case, the group will be repeated as a whole).
      Let's say we wanted to match 'abc', zero or more times (ie. abcabcabc matches, abcccc doesn't). If we tried to use the pattern abc*, the repetition modifier would only apply to the c, because c is the last token before the modifier. In order to get around this, we can group abc ((abc)*), in which case the modifier would apply to the entire group, as if it was a single token.
    • \. specifies a literal dot character. The reason this is needed is because . is a special character in regex, meaning any character. Since we want to match an actual dot character, we need to escape it.

    (captures john.robert.smith@mail.com)

  4. @ is not a special character in regex, so, like all other non-special characters, it matches literally.
    (captures john.robert.smith@mail.com)

  5. [a-z0-9-]+ again defines a repeated character class, like item #2 above.
    (captures john.robert.smith@mail.com)

  6. (\.[a-z0-9-]+)* is almost exactly the same pattern as #3 above.
    (captures john.robert.smith@mail.com)

  7. $ is the end of string anchor. It works the same as ^ above, except matches the end of the string.


With that in mind, it should be a bit clearer how to add a section with captures a plus segment. As we saw above, + is a special character so it has to be escaped. Then, since the + has to be followed by some characters, we can define a character class with the characters we want to match and define its repetition. Finally, we should make the whole group optional because email addresses don't need to have a + segment:

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

When inserted into your regex, it'd look like this:

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


Save your sanity. Get a pre-made PHP RFC 822 Email address parser


I've used this regex to validate emails, and it works just fine with emails that contain a+:

/^(([^<>()[\]\\.,;:\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,}))$/


\+ will match a literal + sign, but be aware: You still won't be close to matching all possible email addresses according to the RFC spec, because the actual regex for that is madness. It's almost certainly not worth it; you should use a real email parser for this.


This is another solution (is similar to the solution found by 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})$


This is the another solution

/^[_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]+)$/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜