159

First of all, I know that using regex for email is not recommended but I gotta test this out.

I have this regex:

\b[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b

In Java, I did this:

Pattern p = Pattern.compile("\\b[A-Z0-9._%-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}\\b");
Matcher m = p.matcher("foobar@gmail.com");

if (m.find())
    System.out.println("Correct!");

However, the regex fails regardless of whether the email is wel-formed or not. A "find and replace" inside Eclipse works fine with the same regex.

Any idea?

Thanks,

Tu Hoang
  • 4,622
  • 13
  • 35
  • 48

23 Answers23

320

FWIW, here is the Java code we use to validate email addresses. The Regexp's are very similar:

public static final Pattern VALID_EMAIL_ADDRESS_REGEX = 
    Pattern.compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$", Pattern.CASE_INSENSITIVE);

public static boolean validate(String emailStr) {
        Matcher matcher = VALID_EMAIL_ADDRESS_REGEX.matcher(emailStr);
        return matcher.matches();
}

Works fairly reliably.

jumping_monkey
  • 5,941
  • 2
  • 43
  • 58
Jason Buberel
  • 4,930
  • 2
  • 19
  • 10
  • 21
    For a simple solution that matches 99.9% of email addresses this is a good solution. – maloney Aug 08 '13 at 11:21
  • 1
    it fails to validate new long domains (longer than 6 chars), e.g. me@iam.digital – boweidmann Feb 08 '22 at 16:09
  • This is utterly incorrect. – EKW Aug 11 '22 at 03:09
  • @EKW Mind expanding on why it is incorrect? – MattMan569 Oct 18 '22 at 17:16
  • @MattMan569 I do, because what people do is they read a comment, make the minimum change to meet that comment, and don't bother learning anything. A change was made to include 6-character domains. OK. Now what about `accountants`? `travelersinsurance`? The spec exists for a reason. – EKW Oct 19 '22 at 18:37
  • Noticed that if you go to regex101 website and try it under Java 8 it gives you an error if you use the dashes right before the closing ] bracket. – CuriousGeo66 Feb 23 '23 at 20:34
184

Here is RFC822 compliant regex adapted for Java:

Pattern ptr = Pattern.compile("(?:(?:\\r\\n)?[ \\t])*(?:(?:(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n)?[ \\t]))*\"(?:(?:\\r\\n)?[ \\t])*)(?:\\.(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n)?[ \\t]))*\"(?:(?:\\r\\n)?[ \\t])*))*@(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*)(?:\\.(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*))*|(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n)?[ \\t]))*\"(?:(?:\\r\\n)?[ \\t])*)*\\<(?:(?:\\r\\n)?[ \\t])*(?:@(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*)(?:\\.(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*))*(?:,@(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*)(?:\\.(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*))*)*:(?:(?:\\r\\n)?[ \\t])*)?(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n)?[ \\t]))*\"(?:(?:\\r\\n)?[ \\t])*)(?:\\.(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n)?[ \\t]))*\"(?:(?:\\r\\n)?[ \\t])*))*@(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*)(?:\\.(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*))*\\>(?:(?:\\r\\n)?[ \\t])*)|(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n)?[ \\t]))*\"(?:(?:\\r\\n)?[ \\t])*)*:(?:(?:\\r\\n)?[ \\t])*(?:(?:(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n)?[ \\t]))*\"(?:(?:\\r\\n)?[ \\t])*)(?:\\.(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n)?[ \\t]))*\"(?:(?:\\r\\n)?[ \\t])*))*@(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*)(?:\\.(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*))*|(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n)?[ \\t]))*\"(?:(?:\\r\\n)?[ \\t])*)*\\<(?:(?:\\r\\n)?[ \\t])*(?:@(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*)(?:\\.(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*))*(?:,@(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*)(?:\\.(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*))*)*:(?:(?:\\r\\n)?[ \\t])*)?(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n)?[ \\t]))*\"(?:(?:\\r\\n)?[ \\t])*)(?:\\.(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n)?[ \\t]))*\"(?:(?:\\r\\n)?[ \\t])*))*@(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*)(?:\\.(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*))*\\>(?:(?:\\r\\n)?[ \\t])*)(?:,\\s*(?:(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n)?[ \\t]))*\"(?:(?:\\r\\n)?[ \\t])*)(?:\\.(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n)?[ \\t]))*\"(?:(?:\\r\\n)?[ \\t])*))*@(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*)(?:\\.(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*))*|(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n)?[ \\t]))*\"(?:(?:\\r\\n)?[ \\t])*)*\\<(?:(?:\\r\\n)?[ \\t])*(?:@(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*)(?:\\.(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*))*(?:,@(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*)(?:\\.(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*))*)*:(?:(?:\\r\\n)?[ \\t])*)?(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n)?[ \\t]))*\"(?:(?:\\r\\n)?[ \\t])*)(?:\\.(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\"(?:[^\\\"\\r\\\\]|\\\\.|(?:(?:\\r\\n)?[ \\t]))*\"(?:(?:\\r\\n)?[ \\t])*))*@(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*)(?:\\.(?:(?:\\r\\n)?[ \\t])*(?:[^()<>@,;:\\\\\".\\[\\] \\000-\\031]+(?:(?:(?:\\r\\n)?[ \\t])+|\\Z|(?=[\\[\"()<>@,;:\\\\\".\\[\\]]))|\\[([^\\[\\]\\r\\\\]|\\\\.)*\\](?:(?:\\r\\n)?[ \\t])*))*\\>(?:(?:\\r\\n)?[ \\t])*))*)?;\\s*)");
String[] emails = { "\"Fred Bloggs\"@example.com", "user@.invalid.com", "Chuck Norris <gmail@chucknorris.com>", "webmaster@müller.de", "matteo@78.47.122.114" };
for (String email : emails) {
    System.out.println(email + " is " + (ptr.matcher(email).matches() ? "valid" : "invalid"));
}

Output:

"Fred Bloggs"@example.com is valid
user@.invalid.com is invalid
Chuck Norris <gmail@chucknorris.com> is valid
webmaster@müller.de is valid
matteo@78.47.122.114 is valid

The regex is taken from this post: Mail::RFC822::Address: regexp-based address validation. The results should coincide with online version.

ejboy
  • 4,081
  • 5
  • 30
  • 32
  • For anyone reading this in 2022, RFC 5322 is the updated version of RFC 822 - https://www.rfc-editor.org/rfc/pdfrfc/rfc5322.txt.pdf `regexPattern = "^[a-zA-Z0-9_!#$%&'*+/=?``{|}~^.-]+@[a-zA-Z0-9.-]+$";` – dev_in_prog Dec 02 '22 at 22:52
  • @dev_in_prog I don't believe this regex is complete. https://stackoverflow.com/questions/13992403/regex-validation-of-email-addresses-according-to-rfc5321-rfc5322 – ejboy Dec 04 '22 at 01:08
19

Don't. You will never end up with a valid expression.

For example these are all valid email addresses:

"Abc\@def"@example.com
"Fred Bloggs"@example.com
"Joe\\Blow"@example.com
"Abc@def"@example.com
customer/department=shipping@examp­ le.com
$A12345@example.com
!def!xyz%abc@example.com
_somename@example.com
matteo(this is a comment).corti@example.com
root@[127.0.0.1]

Just to mention a few problems:

  • you don't consider the many forms of specifying a host (e.g, by the IP address)
  • you miss valid characters
  • you miss non ASCII domain names

Before even beginning check the corresponding RFCs

Matteo
  • 14,696
  • 9
  • 68
  • 106
  • 3
    E-mails with spaces? That's seems pretty invalid even if somewhere it was decided that e-mails can have spaces. – The Berga Jul 25 '16 at 11:25
  • 1
    @MenukaIshan As they claim themselves regex will never be completely OK. You can test several examples above. Now the question is why stick to regeres where there are implementations that work? – Matteo Dec 15 '16 at 09:49
  • 1
    @Matteo Can you give me such example that don't require regex? I know about Hibernate Validator @ Email annotation. Is that type of things are you talking about? Anyway I would love to know your examples so that I will able to use them in my future developments. Thank you. – Menuka Ishan Dec 15 '16 at 10:51
  • Which language are using? – Matteo Dec 15 '16 at 11:51
  • Literally the only correct answer on this page. – EKW Aug 11 '22 at 03:24
10

That's because you are forgetting case insensitivity :

Pattern regex = Pattern.compile("\\b[\\w.%-]+@[-.\\w]+\\.[A-Za-z]{2,4}\\b");

This matches your example, although it ignores many valid e-mails.

FailedDev
  • 26,680
  • 9
  • 53
  • 73
8

One another simple alternative to validate 99% of emails

public static final String EMAIL_VERIFICATION = "^([\\w-\\.]+){1,64}@([\\w&&[^_]]+){2,255}.[a-z]{2,}$";
Armer B.
  • 753
  • 2
  • 9
  • 25
  • 5
    I like this one as it is simple and understandable, one thing it is missing is international language support (föö@bar.com is valid nowadays) just switching the \w for \p{L} allows letters of any language. I ended up with: "^([\p{L}-_\.]+){1,64}@([\p{L}-_\.]+){2,255}.[a-z]{2,}$" – Tobi Nonymous Nov 23 '18 at 11:46
  • Simple, understandable, and doesn't validate email addresses properly. – EKW Aug 11 '22 at 03:20
6

This is a valid regex for validating e-mails. It's totally compliant with RFC822 and accepts IP address and server names (for intranet purposes).

public static boolean isEmailValid(String email) {
    final Pattern EMAIL_REGEX = Pattern.compile("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", Pattern.CASE_INSENSITIVE);
    return EMAIL_REGEX.matcher(email).matches();
}

Here are some output examples, when you call isEmailValid(emailVariable):

john@somewhere.com // valid
john.foo@somewhere.com // valid
john.foo+label@somewhere.com // valid (with +label - Gmail accepts it!)
john@192.168.1.10 // valid (with IP addresses)
john+label@192.168.1.10 // valid (with +label and IP address)
john.foo@someserver // valid (with no first domain level)
JOHN.FOO@somewhere.com // valid (case insensitive)
@someserver // invalid
@someserver.com // invalid
john@. // invalid
.@somewhere.com // invalid
shimatai
  • 1,759
  • 16
  • 18
  • This is at least *marginally* more correct than the others here, but it assumes English is the only language in the world. – EKW Aug 11 '22 at 03:17
  • @EKW Not at all. This RegEx pattern can also validate emails with diacritics, like "constelação@gmail.com" or "àéíö@gmail.com" – shimatai Aug 11 '22 at 13:28
  • Unless Java started doing something unusual at some point, it does not. You would need to add an explicit list of accented characters. But it also doesn't handle Chinese/Japanese, Korean, Russian, Arabic, or any number of other languages. – EKW Aug 12 '22 at 14:28
3

Thanks to @Jason Buberel's answer, I think lowercase letters must be validated by the RegEX. So the following is correct:

[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}

Now, both developer961@mail.com and DEV961@yahoo.COM are valid!
Note that \. should be \\. to escape . and have \. itself. Since, . is a meaningful character in java RegEX means all characters.

Mohsen Abasi
  • 2,050
  • 28
  • 30
2

You can use this method for validating email address in java.

public class EmailValidator {
    private Pattern pattern;
    private Matcher matcher;

    private static final String EMAIL_PATTERN = 
        "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@"
        + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";

    public EmailValidator() {
        pattern = Pattern.compile(EMAIL_PATTERN);
    }

    /**
    * Validate hex with regular expression
    * 
    * @param hex
    *            hex for validation
    * @return true valid hex, false invalid hex
    */
    public boolean validate(final String hex) {

    matcher = pattern.matcher(hex);
    return matcher.matches();

    }
}
Maksim
  • 16,635
  • 27
  • 94
  • 135
Chanaka udaya
  • 5,134
  • 4
  • 27
  • 34
2

I came across this post and tried some answers, however did not find one that supported all the things I needed.

  • Unicode chars in our case especial for german (ÄÖÜäöüß)
  • The gmail + feature: my.gmail+@gmail.com

I found a comprehensive listing of patterns at https://www.baeldung.com/java-email-validation-regex where I found the unicode and gmail approaches:

uniCodeRegex = "^(?=.{1,64}@)[\\p{L}0-9_-]+(\\.[\\p{L}0-9_-]+)*@" 
    + "[^-][\\p{L}0-9-]+(\\.[\\p{L}0-9-]+)*(\\.[\\p{L}]{2,})$";
gmailRegex = "^(?=.{1,64}@)[A-Za-z0-9\\+_-]+(\\.[A-Za-z0-9\\+_-]+)*@" 
    + "[^-][A-Za-z0-9\\+-]+(\\.[A-Za-z0-9\\+-]+)*(\\.[A-Za-z]{2,})$";

TL,DR: and combined them by replacing A-Za-z with \\p{L} for unicode letters

combined = "^(?=.{1,64}@)[\\p{L}0-9\\+_-]+(\\.[\\p{L}0-9\\+_-]+)*@"
        + "[^-][\\p{L}0-9\\+-]+(\\.[\\p{L}0-9\\+-]+)*(\\.[\\p{L}]{2,})$"

Kotlin test example:

val p = Pattern.compile(patternRegex)
assertThat(p.matcher("user@domain.com").find()).isTrue()
Martin
  • 680
  • 8
  • 12
2

Is maching set to CASE_INSENSITIVE?

Grzegorz Rożniecki
  • 27,415
  • 11
  • 90
  • 112
1

General Email format (RE) which include also domain like co.in, co.uk, com, outlook.com etc.

And rule says that :

  • Uppercase and lowercase English letters (a-z, A-Z)
  • Digits 0 to 9
  • Characters ! # $ % & ' * + - / = ? ^ _ ` { | } ~ Character.
  • (dot, period, full stop) provided that it is not the first or last character, and provided also that it does not appear two or more times consecutively.

    [a-zA-Z0-9]+[._a-zA-Z0-9!#$%&'*+-/=?^_`{|}~]*[a-zA-Z]*@[a-zA-Z0-9]{2,8}.[a-zA-Z.]{2,6}
    
Hitesh Kalwani
  • 573
  • 5
  • 9
  • English is the only language in the world? – EKW Aug 11 '22 at 03:20
  • I took the reference of the English language. You can use any language's alphabates (Unicode value) range and put it here in the RE. I guess we are using StackOverflow for reference, not for the exact answer. Eventually, it's a bad practice if someone is following such practices. – Hitesh Kalwani Aug 11 '22 at 04:02
  • Yes, people use these answers all the time. That's how I end up back here downvoting even more answers to this question: Because I've encountered another one of these in the wild, and it has refused a valid email address. – EKW Aug 12 '22 at 14:29
  • Could you please mention the example? I’ll try to provide you the proper solution. Thank you, – Hitesh Kalwani Aug 13 '22 at 16:57
  • I'm not going to send you one of the millions of websites that use one of these poor regular expressions, no. But you can have test cases. https://github.com/skeggse/isemail/blob/master/test/tests.json – EKW Aug 14 '22 at 17:45
1

I have tested this below regular expression for single and multiple consecutive dots in domain name -

([A-Za-z0-9-_.]+@[A-Za-z0-9-_]+(?:\.[A-Za-z0-9]+)+)

and here are the examples which were completely fulfilled by above regex.

End_user@live.com
End.u@exm-tech.net
enduser9876@gmail.in
end_user@mywebsite.ac.in.gui
Another984.User2@mail.edu.sg
Another987_User5@mail.show.au
Slow_User@example_domain.au.in
iamthemostsimpleremailhere@example.com

I have tried to cover maximum commonly used email id's validation by this above illustrated regex and yet working...

If you still know some consequentially used email id's had left here, please let me know in comment section!

ArifMustafa
  • 4,617
  • 5
  • 40
  • 48
  • It doesn't matter whether or not you think email address formats are "consequentially used," because you don't get to determine that. The RFC does. Your regex does not work. – EKW Aug 11 '22 at 03:15
  • @EKW Oops!, but the regex is already working, and already given various email patterns also... you explicitly not mentioned that the regex is not working for which email address any example?, please don't make unnecessary everywhere comments, otherwise where is your correct regex? – ArifMustafa Aug 15 '22 at 01:36
  • http://web.archive.org/web/20220706115526/https://medium.com/hackernoon/the-100-correct-way-to-validate-email-addresses-7c4818f24643 – EKW Aug 16 '22 at 03:52
  • And if you don't want me to keep commenting on bad "email validation" regular expressions, perhaps people should stop posting them. – EKW Aug 16 '22 at 03:53
  • Nothing is bad email but your way of comment and approach, you just found something in medium this year, and started comments on others post, without testing the source and even there are examples on which the regex had been tested, but it seems like you are comment hero instead of mentioning the improved version of answer in reply, just stop here your wrong approach. – ArifMustafa Aug 16 '22 at 07:12
1

You can use a simple regular expression for validating email id,

public boolean validateEmail(String email){
  return Pattern.matches("[_a-zA-Z0-9]+(\\.[A-Za-z0-9]*)*@[A-Za-z0-9]+\\.[A-Za-z0-9]+(\\.[A-Za-z0-9]*)*", email)
}

Description:

  1. [_a-zA-Z0-9]+ - it will accept all A-Z, a-z, 0-9 and _ (+ mean it must be occur)
  2. (\.[A-Za-z0-9]) - it's optional which will accept . and A-Z, a-z, 0-9( * mean its optional)
  3. @[A-Za-z0-9]+ - it will accept @ and A-Z,a-z,0-9
  4. \.[A-Za-z0-9]+ - its for . and A-Z,a-z,0-9
  5. (\.[A-Za-z0-9]) - it occur, . but its optional
Vivek Hande
  • 929
  • 9
  • 11
1

Modification of Armer B. answer which didn't validate emails ending with '.co.uk'

public static boolean emailValidate(String email) {
    Matcher matcher = Pattern.compile("^([\\w-\\.]+){1,64}@([\\w&&[^_]]+){2,255}(.[a-z]{2,3})+$|^$", Pattern.CASE_INSENSITIVE).matcher(email);

    return matcher.find();
}
Alex Hodson
  • 108
  • 1
  • 6
  • Replacing a broken regex with another broken regex is not the solution. Your regex doesn't work, and has never worked, for valid email addresses. – EKW Aug 11 '22 at 03:13
1
import java.util.Scanner;

public class CheckingTheEmailPassword {

    public static void main(String[] args) {
        String email = null;
        String password = null;
        Boolean password_valid = false;
        Boolean email_valid = false;

        Scanner input = new Scanner(System.in);
        do {
            System.out.println("Enter your email: ");
            email = input.nextLine();

            System.out.println("Enter your passsword: ");
            password = input.nextLine();

            // checks for words,numbers before @symbol and between "@" and ".".
            // Checks only 2 or 3 alphabets after "."
            if (email.matches("[\\w]+@[\\w]+\\.[a-zA-Z]{2,3}"))
                email_valid = true;
            else
                email_valid = false;

            // checks for NOT words,numbers,underscore and whitespace.
            // checks if special characters present
            if ((password.matches(".*[^\\w\\s].*")) &&
            // checks alphabets present
                    (password.matches(".*[a-zA-Z].*")) &&
                    // checks numbers present
                    (password.matches(".*[0-9].*")) &&
                    // checks length
                    (password.length() >= 8))
                password_valid = true;
            else
                password_valid = false;

            if (password_valid && email_valid)
                System.out.println(" Welcome User!!");
            else {
                if (!email_valid)
                    System.out.println(" Re-enter your email: ");
                if (!password_valid)
                    System.out.println(" Re-enter your password: ");
            }

        } while (!email_valid || !password_valid);

        input.close();

    }

}
Abhinav Suman
  • 940
  • 1
  • 9
  • 29
0

Regex : ^[\\w!#$%&’*+/=?{|}~^-]+(?:\.[\w!#$%&’*+/=?{|}~^-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}$

public static boolean isValidEmailId(String email) {
        String emailPattern = "^[\\w!#$%&’*+/=?`{|}~^-]+(?:\\.[\\w!#$%&’*+/=?`{|}~^-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}$";
        Pattern p = Pattern.compile(emailPattern);
        Matcher m = p.matcher(email);
        return m.matches();
    }
Neo
  • 3,546
  • 1
  • 24
  • 31
0

If you want to allow non-latain characters, this one works quite well for me.

"^[\\p{L}\\p{N}\\._%+-]+@[\\p{L}\\p{N}\\.\\-]+\\.[\\p{L}]{2,}$"

It does not allow IP's after the @ but most valid email in the from of xxx@xxx.TDL could be validated with it. \p{L} validates UTF-Letters and \p{N} validates UTF-Numbers. You can check this doc for more information.

Nabil A.
  • 3,270
  • 17
  • 29
  • Close, but no cigar. Points for being one of the only regular expressions on this page which thought to support Unicode, but it excludes RFC-valid email addresses. – EKW Aug 11 '22 at 03:23
0

Regex for Facebook-like validation:

public static final String REGEX_EMAIL_VALIDATION = "^[\\w-\\+]+(\\.[\\w]+)*@[\\w-]+(\\.[\\w]+)*(\\.[a-zA-Z]{2,})$";

Dto for Unit tests(with Lombok):

@Data
@Accessors(chain = true)
@FieldDefaults(level = AccessLevel.PRIVATE)
public class UserCreateDto {

    @NotNull
    @Pattern(regexp = REGEX_EMAIL_VALIDATION)
    @Size(min = 1, max = 254)
    String email;
}

Valid/invalid emails below with Unit tests:

public class UserCreateValidationDtoTest {

private static final String[] VALID_EMAILS = new String[]{"email@yahoo.com", "email-100@yahoo.com",
        "Email.100@yahoo.com", "email111@email.com", "email-100@email.net",
        "email.100@email.com.au", "emAil@1.com", "email@gmail.com.com",
        "email+100@gmail.com", "emAil-100@yahoo-test.com", "email_100@yahoo-test.ABC.CoM"};
private static final String[] INVALID_EMAILS = new String[]{"あいうえお@example.com", "email@111",
        "email", "email@.com.my", "email123@gmail.", "email123@.com", "email123@.com.com",
        ".email@email.com", "email()*@gmAil.com", "eEmail()*@gmail.com", "email@%*.com", "email..2002@gmail.com",
        "email.@gmail.com", "email@email@gmail.com", "email@gmail.com."};
private Validator validator;

@Before
public void setUp() throws Exception {
    ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    validator = factory.getValidator();
}

@Test
public void emailValidationShouldBeValid() throws Exception {
    Arrays.stream(VALID_EMAILS)
            .forEach(email -> {
                        Set<ConstraintViolation<UserCreateDto>> violations = validateEmail(
                                new UserCreateDto().setEmail(email));
                        System.out.println("Email: " + email + ", violations: " + violations);
                        Assert.assertTrue(violations.isEmpty());
                    }
            );
}

@Test
public void emailValidationShouldBeNotValid() throws Exception {
    Arrays.stream(INVALID_EMAILS)
            .forEach(email -> {
                        Set<ConstraintViolation<UserCreateDto>> violations = validateEmail(
                                new UserCreateDto().setEmail(email));
                        System.out.println("Email: " + email + ", violations: " + violations);
                        Assert.assertTrue(!violations.isEmpty());
                    }
            );
}


private Set<ConstraintViolation<UserCreateDto>> validateEmail(UserCreateDto user) {
    String emailFieldName = "email";
    return validator.validateProperty(user, emailFieldName);
}

}

Oleksandr Yefymov
  • 6,081
  • 2
  • 22
  • 32
  • This is one of the only marginally functional regular expressions on this page. – EKW Aug 11 '22 at 03:18
0

Try the below code for email is format of

jsmith@example.com

1st part -jsmith 2nd part -@example.com

1. In the 1 part it will allow 0-9,A-Z,dot sign(.),underscore sign(_)
 2. In the 2 part it will allow A-Z, must be @ and .

^[a-zA-Z0-9_.]+@[a-zA-Z.]+?\.[a-zA-Z]{2,3}$
Balasubramanian
  • 700
  • 7
  • 26
charan
  • 149
  • 5
0
String emailRegex = "[a-zA-Z0-9_.]+@[a-zA-Z0-9]+.[a-zA-Z]{2,3}[.] {0,1}[a-zA-Z]+";
Pattern.matches(emailRegex,"You_Input_Mail_Id");

This is the regex to match valid email addresses.

kiner_shah
  • 3,939
  • 7
  • 23
  • 37
0

You can checking if emails is valid or no by using this libreries, and of course you can add array for this folowing project.

import org.apache.commons.validator.routines.EmailValidator;

public class Email{
    public static void main(String[] args){
        EmailValidator email = EmailVlidator.getInstance();
        boolean val = email.isValid("george.parcks@gmail.com");
        System.out.println("Mail is: "+val);
        val = email.isValid("hans.riguer.hotmsil.com");
        System.out.print("Mail is: "+val");
    }
}

output :

Mail is: true

Mail is : false

  • 1
    Nice that it is a library but the regex used is really simple... EMAIL_REGEX = "^\\s*?(.+)@(.+?)\\s*$"; – Milo van der Zee Jun 12 '20 at 13:08
  • @MilovanderZee I appreciate your having tried to actually correct them with a real, functioning email regex. – EKW Aug 11 '22 at 03:11
0

If you use Java Bean Validation, an email can be validated with javax.validation.constraints.Email annotation.

If you want to do it manually, you can see how Hibernate Validator (Java Bean Validation implementation) done it:

https://github.com/hibernate/hibernate-validator/blob/master/engine/src/main/java/org/hibernate/validator/internal/constraintvalidators/AbstractEmailValidator.java

Krzysztof
  • 709
  • 6
  • 12
0

You can also use the solution provided by

org.hibernate.validator.constraints.impl.EmailValidator


    public class EmailValidator implements ConstraintValidator<Email, String> {
    private static String ATOM = "[a-z0-9!#$%&'*+/=?^_`{|}~-]";
    private static String DOMAIN = "(" + ATOM + "+(\\." + ATOM + "+)*";
    private static String IP_DOMAIN = "\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\]";

    private java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(
            "^" + ATOM + "+(\\." + ATOM + "+)*@"
                    + DOMAIN
                    + "|"
                    + IP_DOMAIN
                    + ")$",
            java.util.regex.Pattern.CASE_INSENSITIVE
    );

    public void initialize(Email annotation) {
    }

    public boolean isValid(String value, ConstraintValidatorContext context) {
        if ( value == null || value.length() == 0 ) {
            return true;
        }
        Matcher m = pattern.matcher( value );
        return m.matches();
    }
}
Alex Mi
  • 1,409
  • 2
  • 21
  • 35