14
\$\begingroup\$

I need to validate whether my regex is correct for below scenario. Suggestion's if the regex is correct:

Wiki Link Local_part

The local-part of the email address may use any of these ASCII characters.[4] RFC 6531 permits Unicode characters beyond the ASCII range:

  1. Uppercase and lowercase English letters (a–z, A–Z) (ASCII: 65–90, 97–122)
  2. Digits 0 to 9 (ASCII: 48–57)
  3. These special characters: ! # $ % & ' * + - / = ? ^ _ { | } ~ (limited support)
  4. Character . (dot, period, full stop) (ASCII: 46) provided that it is not the first or last character, and provided also that it does not appear two or more times consecutively (e.g. [email protected] is not allowed).
  5. Special characters are allowed with restrictions. They are:
  6. Comments are allowed with parentheses at either end of the local part; e.g. "john.smith(comment)@example.com" and "(comment)[email protected]" are both equivalent to "[email protected]".
  7. International characters above U+007F are permitted by RFC 6531, though mail systems may restrict which characters to use when assigning local parts.

The Regex:

^[a-z0-9][-a-z0-9.!#$%&'*+-=?^_`{|}~\/]+@([-a-z0-9]+\.)+[a-z]{2,5}$

Demo Here

\$\endgroup\$
10
  • 2
    \$\begingroup\$ What language are we talking about? Most languages have libraries for validating emails, and also, regex implementation differs between languages. \$\endgroup\$ Commented Jun 23, 2014 at 11:41
  • \$\begingroup\$ Oops sorry to mention. .net \$\endgroup\$ Commented Jun 23, 2014 at 11:42
  • \$\begingroup\$ .net is not a language, it's a framework. \$\endgroup\$ Commented Jun 23, 2014 at 11:43
  • 2
    \$\begingroup\$ Can you provide some C# code where you perform this check? \$\endgroup\$ Commented Jun 23, 2014 at 11:45
  • 5
    \$\begingroup\$ I'd consider regex to be a domain-specific language. Specifying ".NET Framework Regular Expressions" makes it sufficiently concrete to be on-topic. \$\endgroup\$ Commented Jun 23, 2014 at 11:53

7 Answers 7

35
\$\begingroup\$

I remember having read somewhere (possibly in another Code Review answer) that for an e-mail address, the simplest and most effective validation you can do is to make sure it contains an @. Making it more restrictive than that can often be a risk of invalidating some valid e-mails. You'd be surprised at some examples of valid e-mail addresses.

As an additional example, see the "almost RFC 822 compatible regex" in this answer.

Keep it simple, and don't mark some e-mail addresses that are actually valid as invalid.

email.contains("@")

If you want to be more restrictive than this, use an existing and trusted library for the validation, don't try to make another regex.

For further reading:

\$\endgroup\$
8
  • \$\begingroup\$ Thanks @simon for the list of email addresses. \$\endgroup\$ Commented Jun 23, 2014 at 12:16
  • 4
    \$\begingroup\$ "Some people, when confronted with a problem, think 'I know, I'll use regular expressions.' Now they have two problems."——Jamie Zawinski on regular expressions; paraphrasing the Unix Haters Handbook on sed, paraphrasing David Tilbrook on awk. regex.info/blog/2006-09-15/247 :) \$\endgroup\$ Commented Jun 23, 2014 at 17:20
  • 1
    \$\begingroup\$ The main point being that even if the address is syntactically correct, you have no idea whether it exists. If you need verification, send a verification link to the address. \$\endgroup\$
    – Ingo Bürk
    Commented Jun 23, 2014 at 19:38
  • 1
    \$\begingroup\$ @IngoBürk: That's true, but validation and verification are different things. There's no point verifying invalid data. \$\endgroup\$
    – Magus
    Commented Jun 24, 2014 at 15:19
  • 1
    \$\begingroup\$ If you want to be more restrictive than this, use an existing and trusted library for the validation - In my experience, even library validators are broken. Since then, email.contains("@") is the only thing I'd ever do. \$\endgroup\$
    – Jo So
    Commented Aug 17, 2014 at 2:40
20
\$\begingroup\$

As @Simon pointed out, your regular expression might consider some valid addresses as invalid.

Per this source which I've found somewhere on this Stack Overflow page, this would be RFC5322-compliant:

(?:[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])+)
     \])

Validating emails with a regular expression is ...more complicated than one would think, eh?

I agree with @Simon here, it's probably best to keep it simple, and go with a simple string.Contains() instead of a regular expression. If it's not a matter of life and death, ...don't try to be a regex ninja!

XKCD#208

\$\endgroup\$
1
  • 4
    \$\begingroup\$ Pretty much anything with an xkcd comic gets an up vote. \$\endgroup\$
    – RubberDuck
    Commented Jun 23, 2014 at 13:14
13
\$\begingroup\$

It was suggested that I move this to an answer instead of a comment:

Since you're using .NET, why not just use System.Net.Mail.MailAddress? It already performs validation in its constructor - it will throw a FormatException if the address is invalid.

This is particularly useful if you intend on using the address to actually send email, since you'll likely be using Systen.Net.Mail.MailAddress for it anyways.

This does not get you the regex, but I think a better solution is to avoid regex in this case for the reasons stated in the comments and other answers.

\$\endgroup\$
3
  • \$\begingroup\$ Why, why, why, WHY haven't I thought if this!?!! Here, have an upvote! ;) \$\endgroup\$ Commented Jun 23, 2014 at 23:56
  • 2
    \$\begingroup\$ +1 I've used this technique multiple times. If it's good enough for the .NET Framework, it's good enough for me. The really long catch-all-edge-cases regex formats are daunting. And they're never quite perfect. \$\endgroup\$
    – user24822
    Commented Jun 24, 2014 at 19:39
  • \$\begingroup\$ This feels like you're using try/catch for control flow since you're forced to catch an exception in the invalid case while trying to validate. \$\endgroup\$
    – Erik
    Commented Nov 18, 2015 at 19:09
3
\$\begingroup\$

I follow the HTML5 spec for validation of email here. (Note that it's not RFC 5322 compatible)

The regex for it is:

/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/

which is simple enough for my needs.

\$\endgroup\$
4
  • 2
    \$\begingroup\$ The important question IMO is not whether or not the regex is simple, it's whether or not it is correct. I believe this regex will incorrectly mark several unusual but valid addresses as invalid. \$\endgroup\$ Commented Jun 23, 2014 at 15:28
  • \$\begingroup\$ True, some will fail, but it has the advantage that the same validation that happens on the browser is also used on the server side. Also I suspect that soon all the "valid" emails that don't pass the check above (ie HTML5 validation) will be changed to be compatible with it. \$\endgroup\$ Commented Jun 23, 2014 at 16:08
  • \$\begingroup\$ @SimonAndréForsberg: Do you have some examples of valid ones not accepted by this regex? \$\endgroup\$
    – Gabe
    Commented Jun 24, 2014 at 0:20
  • 1
    \$\begingroup\$ @SimonAndréForsberg: I.am.a.valid"email address!"@email.host. The spec is uh, quite flexible. \$\endgroup\$
    – Phoshi
    Commented Jun 24, 2014 at 15:18
1
\$\begingroup\$

If you're willing to take a dependency on System.ComponentModel.DataAnnotations then you can use the EmailAddressAttribute to do all the heavy lifting for you. I tend to use it as an extension method as follows:

private static readonly EmailAddressAttribute EmailValidator = new EmailAddressAttribute();

public static bool IsValidEmail(this string email)
{
    // You can also add validation against length if you want
    return !string.IsNullOrWhiteSpace(email) && EmailValidator.IsValid(email); 
}
\$\endgroup\$
1
\$\begingroup\$

Email validation regex:

^[a-z0-9][-a-z0-9._]+@([-a-z0-9]+\.)+[a-z]{2,5}$

Or

^[a-z0-9][-a-z0-9._]+@([-a-z0-9]+[.])+[a-z]{2,5}$

Test it out in this Demonstration

\$\endgroup\$
0
\$\begingroup\$
const re_host = '(([a-z0-9-]+\.)+[a-z]+|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3})';
const re_localpart = '[a-z0-9!#\$%&\'*\+-/=\?\^_`{|}\~\.]+';

Take these two constants, and concatenate them like this re_localpart + '@' + re_host and you have a regular expression to validate an email address. Note that this is a PHP regex.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.