Email Validation Regex

Stop Googling and start validating. Grab a production-ready pattern, test cases & language-specific snippets — all on one page.

RFC 5322-Inspired: Balances correctness & performance.
64/254 Length Guards: Protects local-part & full address limits.
Copy-Paste Ready: Works in all major regex engines.

Quick Test Suite

Validate the pattern against these addresses

Should Fail ❌

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.