Email Validation Regex
Stop Googling and start validating. Grab a production-ready pattern, test cases & language-specific snippets — all on one page.
Recommended Pattern
One regex to rule them all
This pattern covers the vast majority of real-world email addresses while remaining readable and fast. It enforces the 64
/254
length limits and supports IPv4/IPv6 literals.
^(?=.{1,254}$)(?=.{1,64}@)[A-Za-z0-9!#$%&'*+/=?^_{|}~-]+(?:\\.[A-Za-z0-9!#$%&'*+/=?^_{|}~-]+)*@(?:(?:[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?\\.)+[A-Za-z]{2,}|\\[(?:IPv6:[A-F0-9]{0,4}(?::[A-F0-9]{0,4}){2,7}|(?: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]?))\\]$
Tip: Use a case-insensitive flag (i
) if your engine treats literals as case-sensitive.
Quick Test Suite
Validate the pattern against these addresses
Should Match ✅
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- user@[192.168.1.10]
- user@[IPv6:2001:db8::1]
Should Fail ❌
- plainaddress
- user@example,com
- [email protected]
- [email protected]
- [email protected]
- [email protected]
- "quoted@domain"@example.com
Language Examples
Drop-in snippets for your stack
Copy the snippet for your favourite language and replace <EMAIL>
with user input.
JavaScript
const pattern = ^(?=.{1,254}$)(?=.{1,64}@)[A-Za-z0-9!#$%&'*+/=?^_{|}~-]+(?:\\.[A-Za-z0-9!#$%&'*+/=?^_{|}~-]+)*@(?:(?:[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?\\.)+[A-Za-z]{2,}|\\[(?:IPv6:[A-F0-9]{0,4}(?::[A-F0-9]{0,4}){2,7}|(?: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]?))\\]$;
function isValid(email) {
return new RegExp(pattern, 'i').test(email);
}
console.log(isValid('[email protected]')); // true
Python
import re
PATTERN = r"""^(?=.{1,254}$)(?=.{1,64}@)[A-Za-z0-9!#$%&'*+/=?^_{|}~-]+(?:\\.[A-Za-z0-9!#$%&'*+/=?^_{|}~-]+)*@(?:(?:[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?\\.)+[A-Za-z]{2,}|\\[(?:IPv6:[A-F0-9]{0,4}(?::[A-F0-9]{0,4}){2,7}|(?: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]?))\\]$"""
def is_valid(email: str) -> bool:
return re.fullmatch(PATTERN, email, flags=re.IGNORECASE) is not None
print(is_valid("[email protected]")) # True
PHP
$pattern = '/^(?=.{1,254}$)(?=.{1,64}@)[A-Za-z0-9!#$%&'*+/=?^_{|}~-]+(?:\\.[A-Za-z0-9!#$%&'*+/=?^_{|}~-]+)*@(?:(?:[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?\\.)+[A-Za-z]{2,}|\\[(?:IPv6:[A-F0-9]{0,4}(?::[A-F0-9]{0,4}){2,7}|(?: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]?))\\]$/i';
function isValid(string $email): bool {
global $pattern;
return preg_match($pattern, $email) === 1;
}
echo isValid('[email protected]') ? 'valid' : 'invalid';
Java
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class EmailValidator {
private static final Pattern PATTERN = Pattern.compile("^(?=.{1,254}$)(?=.{1,64}@)[A-Za-z0-9!#$%&'*+/=?^_{|}~-]+(?:\\.[A-Za-z0-9!#$%&'*+/=?^_{|}~-]+)*@(?:(?:[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?\\.)+[A-Za-z]{2,}|\\[(?:IPv6:[A-F0-9]{0,4}(?::[A-F0-9]{0,4}){2,7}|(?: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]?))\\]$", Pattern.CASE_INSENSITIVE);
public static boolean isValid(String email) {
Matcher matcher = PATTERN.matcher(email);
return matcher.matches();
}
public static void main(String[] args) {
System.out.println(isValid("[email protected]"));
}
}
FAQs
Frequently Asked Questions
Everything you want to know about email regexes
Why is email validation with regex challenging?
The RFC 5322 spec allows a vast range of characters and edge-cases (quoted strings, comments, IP-literals). A production-safe pattern should balance correctness with performance and readability.
Is this regex 100 % RFC-compliant?
It covers 99 % of real-world addresses while keeping the pattern maintainable. Ultra-strict patterns become unreadable and slow. For mission-critical validation, combine regex with DNS, SMTP and disposable detection (see Call to Action below).
Should I trim whitespace before testing?
Yes. Always normalise input by trimming spaces and converting Unicode full-width characters to ASCII equivalents before applying the regex.
How do I allow international (IDN) domains?
Convert Unicode domains to Punycode (e.g. café.com → xn--caf-dma.com) before testing, or use a library that supports Unicode directly.
What about length limits?
RFC limits: local-part ≤ 64 chars, entire address ≤ 254 chars. The recommended pattern enforces both with look-aheads.
Go Beyond Regex
Syntax is just the first step. Verify MX records, SMTP handshake, disposable providers and more with Heybounce's real-time API.