/^/
MediumValidation4 min read

Email Regex

Validates common email address formats by requiring a local part, an @ symbol, a domain, and a top-level domain of at least two letters.

#email#validation#forms#input-validation#regex#string-matching

Regex Pattern

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

Pattern Breakdown

Hover over a token to see what it does.

^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$
TokenMeaning
^Anchors the match to the start of the string
[A-Za-z0-9._%+-]+One or more letters, digits, dots, underscores, percent signs, plus signs, or hyphens for the local part
@Literal @ symbol separating the local part from the domain
[A-Za-z0-9.-]+Domain name made of letters, digits, dots, and hyphens
\.Literal dot immediately before the top-level domain
{2,}At least two characters required for the top-level domain (e.g. com, io, info)
$Anchors the match to the end of the string

Detailed Explanation

What it does

This pattern checks that a string looks like a syntactically valid email address: a local part before the @, an @ symbol, a domain name, and a top-level domain of at least two letters. It rejects strings with spaces, missing @ symbols, or missing top-level domains.

Why it works

The local part character class allows the common set of characters permitted before the @ in everyday addresses. After the @, a domain character class permits letters, digits, dots, and hyphens, and the pattern forces at least one literal dot followed by two or more letters so a bare hostname without a TLD is rejected. Anchoring with ^ and $ ensures the entire string is validated rather than just a substring.

Common use cases

  • Client-side form validation before submitting a signup or contact form
  • Quick sanity checks on CSV imports or bulk-uploaded contact lists
  • Filtering log lines or text for strings that look like email addresses
  • Guarding an API endpoint against obviously malformed email input

Edge cases

  • Addresses with plus-tags like user+newsletter@gmail.com are matched, which is usually desired
  • Consecutive dots in the domain (user@ex..com) are technically allowed by this simplified pattern
  • Quoted local parts or IP-literal domains (RFC 5321 edge cases) are not supported
  • Internationalized domain names with non-ASCII characters will not match without extra Unicode handling
  • A trailing dot after the TLD (user@example.com.) is correctly rejected

Limitations

  • Does not perform full RFC 5321/5322 compliance, only practical everyday validation
  • Cannot verify that the domain actually exists or accepts mail (no DNS/MX lookup)
  • Does not support internationalized (Unicode) email addresses out of the box
  • Allows some technically invalid domains like double dots that stricter validators would reject

Interactive Tester

Edit the pattern or text below — matching runs live in your browser.

user@gmail.com first.last+tag@sub.example.co.uk a.b_c-d@my-domain.io

Test Cases

Editable — add your own inputs to see if they pass.

InputExpectedResult
Pass
Pass
Pass
Pass
Pass
Pass
Pass
Pass
Pass
Pass

Language Variants

Production-ready examples in 12 languages.

const emailRegex = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/;
console.log(emailRegex.test('user@gmail.com')); // true

Common Mistakes

Forgetting to anchor the pattern with ^ and $, allowing partial matches inside longer strings

Fix: Always anchor with ^ and $ (or use .matches() in languages where match already anchors) so the whole string must be a valid email

Trying to write a single regex that fully implements RFC 5322, resulting in an unreadable and still-incomplete pattern

Fix: Use a practical pattern like this one for UX-level validation and confirm real deliverability with a confirmation email

Assuming this regex verifies the domain exists or can receive mail

Fix: Pair regex validation with an MX-record lookup or send a verification email for true deliverability checks

Performance Notes

  • The local-part and domain character classes are possessive by nature since they don't overlap, so catastrophic backtracking is not a concern here
  • Anchoring with ^ and $ lets the engine fail fast on obviously malformed strings
  • For very high-throughput validation, precompile the regex once and reuse it rather than recreating it per call

Browser Compatibility

EngineSupportedNotes
ChromeYes
FirefoxYes
SafariYes
EdgeYes
Node.jsYes