How to validate an email address
Short answer
A simple regular expression checks the general shape: something, @, a domain with a dot:
void main() {
String pattern = "^[\\w.+-]+@[\\w-]+(\\.[\\w-]+)+$";
IO.println("anna@example.com".matches(pattern));
IO.println("anna@example".matches(pattern));
IO.println("anna example.com".matches(pattern));
}Output:
true
false
falseA precompiled pattern
String.matches() compiles the expression again every time. If you validate many values, create the Pattern once:
static final Pattern EMAIL = Pattern.compile("^[\\w.+-]+@[\\w-]+(\\.[\\w-]+)+$");
void main() {
var emails = List.of("oleg@mail.de", "bad@", "a.b+tag@site.co.uk");
for (String email : emails) {
IO.println(email + " -> " + EMAIL.matcher(email).matches());
}
}Output:
oleg@mail.de -> true
bad@ -> false
a.b+tag@site.co.uk -> trueBefore validation
Users often type spaces and capital letters. Normalize the address before checking it:
void main() {
String input = " Anna@Example.COM ";
String email = input.strip().toLowerCase(Locale.ROOT);
IO.println(email);
}Output:
anna@example.comCommon mistake
Trying to write a "perfect" expression. The email standard is very complex, and strict checks reject real addresses. Check the shape with a simple pattern and the existence of the address with a confirmation email. On the other hand, a too simple .+@.+ lets obvious mistakes through:
void main() {
IO.println("a@b@c".matches(".+@.+"));
}Output:
trueFunctions used in this recipe
- String.matches() — Checks whether the whole string matches a regular expression.
- Pattern.compile() — Compiles a regular expression into a Pattern object that can be reused many times.
- String.indexOf() — Finds the position of the first occurrence of a character or a substring.