Testing an Email Validation Pattern

Paste an email pattern and a batch of real and edge-case addresses to see exactly which ones pass and which ones fail, with every match and capture group highlighted live.

How to Test an Email Validation Regex

An email pattern that looks correct on paper rarely survives contact with real addresses. [email protected] is a legal address under the grammar the internet standards actually define, yet a pattern built only around the shape [email protected] rejects it outright, and that gap only shows up once a real user tries to sign up with it.1 Testing a validation pattern against a mixed batch of real and edge-case inputs, before it reaches a signup form, catches that failure in seconds instead of after a support ticket arrives.

Run this check yourself in the Regex Tester & Match Debugger.

Open in the tool →

What a shape-only email pattern misses

Most hand-written email patterns start from a single example: one name, one dot, one domain. That shape works for the address the author happened to type while testing, but real inboxes send addresses that stretch the definition in every direction a narrow pattern never anticipated. A plus-addressed sign-up, a subdomain-hosted mailbox, and a two-letter country-code domain are all completely ordinary in production traffic, not edge cases invented to break your form.

Because the tester runs your pattern through the browser's native RegExp engine, the same engine Node.js and every browser-based signup form already use, whatever passes here behaves identically once the pattern ships.2 Pasting a batch of real addresses, separated by line breaks or commas, into the test text field turns an abstract pattern into a concrete pass/fail list you can read at a glance.

Reading the highlight against a realistic address list

A useful test batch mixes addresses that should pass with ones that should not: a plain address, a plus-tagged address, a subdomain address, and then a handful of deliberately broken strings like a bare word with no @ or a string with two @ signs. Every match highlights inline against the text you pasted, so you see which lines the pattern actually caught without reading the pattern itself line by line.

The group inspector beside the editor adds a second layer worth checking. If your pattern captures the local part and the domain separately, each captured group shows its own text and character range the moment a line matches, confirming the split lands exactly where a downstream script would expect it to.

Turning flags on and off changes what "correct" means

The five flag toggles above the pattern field are not cosmetic. Toggling case-insensitivity matters immediately for email testing, since the local part of an address is case-sensitive by the relevant standard but most mail providers treat it as case-insensitive in practice, and a pattern anchored with the wrong assumption either rejects a valid capitalized address or accepts one the receiving server would actually treat as a duplicate.3

Global mode matters just as much once your test string holds more than one address per line. With the flag off, matching stops at the first hit and every address after it in that line goes unchecked, which can hide a second broken address sitting right next to a valid one.4 Toggling it on and re-running the same test batch is a fast way to confirm you are actually validating everything you pasted, not just the first candidate the engine happened to find.

Matching what your code will actually run

Flags copied inconsistently between this tester and your application code are one of the most common reasons a pattern "works here" and fails once it ships. Confirm the flag combination shown above the pattern field matches exactly what your validation function passes to RegExp, character for character, before treating a passing test batch as proof the code path itself is correct.

Once the flags line up, the pattern's behavior here is not just a preview: it is the identical computation your production code will run, on the identical engine, given the identical input. Copying the flag string alongside the pattern whenever you save a working version, rather than just the pattern text alone, removes an entire category of "it worked in the tester" bug reports before they ever get filed.

Deciding how strict your validation actually needs to be

A regular expression generated to match every rule in the full email grammar, rather than written by hand, runs to thousands of characters and still cannot handle nested comments inside an address without a separate pre-processing step first, because the grammar permits quoted local parts, embedded comments, and other rarely-used syntax most signup forms never need to accept.5 For nearly every real product, a shorter pattern that rejects only the obviously malformed inputs, missing @, missing domain, no top-level domain, and lets a confirmation email handle the rest of the verification is the more practical choice.

That tradeoff is exactly what a worked test batch surfaces. If your pattern rejects a legitimately unusual but valid address more often than it catches a genuinely malformed one, the pattern is stricter than your product needs, and loosening it slightly usually costs less than the support tickets a false rejection generates over the following months.

Picking a strictness level that matches your actual signup flow

Deciding where that line sits is a product judgment, not a purely technical one, and testing against a realistic batch of addresses is how you find out where your current pattern actually draws it. A pattern paired with email confirmation can afford to be looser, since a bad address simply never receives the confirmation link, while a pattern standing in as the only check before an address gets billed or messaged directly needs to lean stricter.

Revisiting the same test batch after any change to the pattern, rather than trusting memory of what it used to reject, keeps that tradeoff a deliberate choice instead of something that quietly drifts with every small edit. Saving that batch alongside the pattern, in a comment or a linked share URL, means the next person to touch the pattern inherits the same reasoning instead of having to reconstruct it from scratch.

When to use this

Use this guide whenever you need to test an email validation pattern against a batch of real and edge-case addresses before wiring it into a signup form or API validator.

Examples

Testing a general-purpose email pattern against a mixed batch

Before
Pattern: [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}
Test text: [email protected], [email protected], not-an-email, user@@example.com
After
The first two addresses highlight as matches; the last two do not, since neither has a valid local part and domain separated by a single @.

This is the same "Email address" pattern available from the Snippets menu inside the tool.

Sources
  1. 1.

    IETF, "Internet Message Format," RFC 5322, October 2008. https://www.rfc-editor.org/rfc/rfc5322

  2. 2.

    MDN Web Docs, "RegExp," developer.mozilla.org, accessed August 2026. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp

  3. 3.

    J. Klensin, "Simple Mail Transfer Protocol," RFC 5321, IETF, October 2008. https://www.rfc-editor.org/rfc/rfc5321

  4. 4.

    MDN Web Docs, "RegExp.prototype.global," developer.mozilla.org, accessed August 2026. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/global

  5. 5.

    Paul Warren, "Mail::RFC822::Address: regexp-based address validation," pdw.ex-parrot.com, accessed August 2026. https://pdw.ex-parrot.com/Mail-RFC822-Address.html

FAQ

Usually not. The complete grammar permits rarely-used syntax like quoted local parts, and a pattern built to match all of it becomes thousands of characters long while still misclassifying some edge cases. Most products are better served by a shorter pattern that rejects only obviously malformed input and lets a confirmation email verify the rest.

Check the flags first. A pattern tested with the case-insensitive flag on behaves differently once that flag is missing from the RegExp your code actually constructs. Confirm the flag string shown above the pattern field matches what your validation function passes, character for character.

No. A regular expression can only check the shape of a string, not whether a mail server exists at that domain or accepts mail. CapyToolkit's tester validates syntax only; pair it with an actual delivery attempt or a confirmation email if you need to confirm the address is live.

Yes. Paste multiple addresses into the test text field, one per line or separated by any delimiter your pattern accounts for, and enable the Global flag so the engine keeps matching past the first hit instead of stopping there.

Match mode is faster for eyeballing a batch of addresses at once, since every match highlights inline. Unit Tests mode is better once you want to pin specific addresses to specific expectations, since each row gets its own explicit should-match or should-not-match assertion and a pass/fail badge.