Techniques 9 min read

Email Validation Regex: Practical Patterns That Work

Practical email validation regex patterns that actually work, from simple checks to RFC-aware rules, with examples in popular languages. Copy and test them.

ST
Scraping.Pro Team
Data collection for business needs
Published: 23 February 2026

Validating an email address with a regular expression sounds like a one-line problem, but it is one of the most deceptively deep topics in everyday programming. The format is governed by decades of layered standards, every framework ships its own opinion, and modern browsers quietly disagree with the specifications they claim to follow. This guide walks through the patterns developers actually reach for, explains where each one comes from, and points to the authoritative sources behind them.

The patterns below were selected with three priorities in mind: readability, complexity, and relevance to the underlying RFC standards. None of them is "the one correct regex" — that does not exist — but together they cover the range of trade-offs you will face in real projects.


Before You Reach for a Regex

A regular expression can only tell you whether a string is shaped like an email address. It cannot tell you whether the mailbox exists, whether the domain accepts mail, or whether a human will ever read it. The only reliable proof of deliverability is to send a confirmation message and have the recipient act on it — a point made explicitly in the Perl community's long-standing FAQ on the subject.

A second caution: the formal grammar is far more permissive than most people expect. The official syntax for the local part (everything before the @) allows quoted strings, comments, and a long list of special characters that virtually no real-world provider supports. As a result, a regex that is technically correct against the standard will happily accept addresses that no mail server on earth will deliver to. For most applications, a deliberately looser-but-saner pattern is the better engineering choice.

If you want to read the relevant standards directly:


Tools for Testing Your Patterns

Before deploying any of these expressions, test them against a representative sample of addresses — including the awkward edge cases. Several free, browser-based tools let you experiment interactively, highlight matches, and explain each token of your pattern:

For ready-made, peer-reviewed patterns, the community library RegexLib hosts thousands of user-contributed expressions, each with a description and notes on its intended scope: https://regexlib.com/. Quality varies, so always read the description and test before adopting one.


General-Purpose Patterns

These are the everyday workhorses. They are intentionally simpler than the formal grammar, trading completeness for clarity and predictability.

A minimal, readable pattern

This expression handles the overwhelming majority of addresses in active use today. It accepts the common local-part characters and a dotted domain, but it does not support the bracketed IP-address form (e.g. user@[192.168.0.1]):

regex
^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$

A case-folded variant

The pattern below matches only lowercase characters, so you must normalize the input — typically by lowercasing the whole string — before you validate it. (Note that the local part of an address is technically case-sensitive per the SMTP standard, but in practice every major provider treats it case-insensitively, so lowercasing for storage and comparison is safe and common.)

regex
^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,6})$

This one is stricter about structure: it requires a final dotted top-level domain of two to six letters. A consequence is that it rejects bare-domain addresses that have no dot after the @, such as nathan@localhost or addresses that point straight at a top-level domain. Whether that is a feature or a bug depends entirely on your use case.

A more permissive, RFC-flavored pattern

This expression admits the broader set of special characters that the standards permit in the local part (! # $ % & ' * + - / = ? ^ _ \ { | } ~), while still keeping the domain conservative. The\b` word boundaries make it suitable for finding addresses embedded in larger text rather than validating a single field:

regex
/\b[!#$%&'*+\-/=?^_`{|}~a-zA-Z0-9][!#$%&'*+\-/=?^_`{|}~a-zA-Z0-9.]*[!#$%&'*+\-/=?^_`{|}~a-zA-Z0-9]@[a-zA-Z0-9\-][a-zA-Z0-9\-.]+[a-zA-Z0-9\-]\b/g

Like the others in this section, it still requires a dotted domain and therefore will not match an address whose domain is a bare top-level label.


Standards-Compliant Patterns

If you genuinely need to honor the formal grammar, the regex grows dramatically — which is itself a strong argument against this approach for most projects.

A short, RFC-oriented expression

The following pattern is widely circulated as an RFC-aligned validator. It covers the standard local-part character set and a multi-label domain. It is best understood as a close approximation of the grammar rather than a literal, exhaustive implementation of it:

regex
/(?:[a-z0-9!#$%&'*+/=?^_{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?: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]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/g

Notice that this version also handles the bracketed IP-literal domain form that the simpler patterns above omit.

The "monster" regex

There is a famous, enormous regular expression that aims for genuine grammar-level compliance. It was not written by hand — it was generated by stitching together a set of smaller sub-expressions that map directly onto the productions in the original message-format grammar. The well-known generator is the Perl module Mail::RFC822::Address by Paul Warren, which validates addresses against the RFC 822 grammar using regular expressions instead of a recursive-descent parser, making it fast enough for short-lived scripts:

A widely cited, language-portable rendering of this RFC 822 approach (along with an extensive conformance test suite) was published by Cal Henderson: https://code.iamcal.com/php/rfc822/. It is instructive to study, but its sheer size and its acceptance of addresses no real server would route are exactly why most teams choose a simpler pattern.

A short history of the relevant RFCs

The standard has been revised several times, and each new document supersedes the previous one:

Document Year Status
RFC 822 1982 Obsoleted by RFC 2822
RFC 2822 2001 Obsoleted by RFC 5322
RFC 5322 2008 Current Internet Message Format

Separately, RFC 6531 and RFC 6532 extend the rules to allow internationalized (non-ASCII) addresses, such as Unicode characters in the local part: https://www.rfc-editor.org/rfc/rfc6531 and https://www.rfc-editor.org/rfc/rfc6532. When a pattern is described as "RFC-2822 compliant," remember that the current authority is RFC 5322 — and that no single regex captures every nuance of these documents in practice.


Environment-Specific Patterns

Many platforms ship a default email pattern. Reusing the one your framework already provides keeps your behavior consistent with the rest of the ecosystem.

JavaScript- and Perl-compatible

The pattern below is compatible with both JavaScript and Perl regex engines and is a practical balance of strictness and tolerance:

regex
/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/

This closely mirrors the expression that the WHATWG HTML Standard defines for the <input type="email"> control (see the HTML5 section below).

ASP.NET

This is the pattern historically used by the RegularExpressionValidator control in ASP.NET Web Forms. If you build on that stack, matching it keeps client- and server-side validation in agreement:

regex
\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*

Microsoft's reference for the control: https://learn.microsoft.com/en-us/dotnet/api/system.web.ui.webcontrols.regularexpressionvalidator.

HTML5 / WHATWG

The pattern the browser itself applies to <input type="email"> is defined in the living HTML Standard maintained by WHATWG. A simplified form looks like this:

regex
[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*

The specification is candid that this definition is a deliberate "willful violation" of RFC 5322: the committee judged the formal grammar to be at once too strict before the @, too vague after it, and too permissive overall (it allows comments, whitespace, and quoted strings that confuse users) to be useful for a web form. You can read the exact normative text and the precise reference regex on the spec page: https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address. Mozilla's developer reference covers the same control and its pattern attribute: https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/email.

Internationalized (German) example

To accept addresses containing German umlauts (ä ö ü Ä Ö Ü) in either the local part or the domain, a pattern like the following can be used. It is a useful illustration of how to widen the character classes for a specific locale — though for full international support you should follow the RFC 6531/6532 path and, ideally, work with normalized Unicode:

regex
/([-a-z0-9öäüÖÄÜ.]+)@((?:[-a-z0-9öäüÖÄÜ.]+\.)+)([a-zA-Z]{2,4})/gi

Why Browsers and the Standards Disagree

Email validators exist to match the strict-yet-inclusive rules laid down in the RFCs. In recent years, though, browser vendors have increasingly set those rules aside and defined "valid email" on their own terms. The HTML5 email input is the clearest example: by design, browsers accept only a reduced, practical subset of the formats the standards allow.

The result is a usability paradox. An address that is perfectly legal under RFC 5322 — for instance one using internationalized characters permitted by RFC 6532, like exampleś@example.com — may be flagged as invalid by a browser that follows only the WHATWG grammar. Users who type a technically valid address can find themselves blocked, while the validation gives no clear explanation. This divergence between the formal standards and the de-facto browser behavior is worth keeping in mind whenever you rely on built-in form validation.


Recommendation

For the vast majority of applications, a short, readable pattern (such as the WHATWG-aligned expression in the HTML5 section) is the right default. It rejects the obvious mistakes — missing @, missing domain dot, stray whitespace — without dragging in the unwieldy complexity of full grammar compliance, and it matches what browsers already enforce. Reserve the "monster" RFC patterns for the rare cases that truly require them.

Whatever pattern you choose, treat regex as a format check only. To confirm that an address can actually receive mail, verify the domain's MX records and, ultimately, send a confirmation email. No regular expression can do that for you.