Regex Tester JSON Formatter Base64 Tool SQL Parser DOM Analyzer Blog
Regex Patterns for Email Validation

Regex Patterns for Email Validation

By Jumma Dev • 18 Jun 2026 • Updated 1 week ago

Email validation looks simple until a legitimate address fails registration or an obviously invalid address passes.

A regular expression can perform a useful syntax check, but it cannot tell you whether:

  • The mailbox exists
  • The user owns the address
  • The domain currently accepts email
  • A message will be delivered
  • The recipient will engage with the message

For most applications, the safest approach is:

  1. Perform a reasonable syntax check.
  2. Validate again on the server.
  3. Send a verification link.
  4. Mark the address as verified only after the user confirms it.

This guide compares practical email regex patterns, explains their limitations, and provides JavaScript, PHP, Laravel, and Python examples.

Email Validation Has Several Layers

“Email validation” can refer to different checks.

Syntax validation

Checks whether the input resembles an email address:

user@example.com

A regex or validation library can perform this check.

Domain validation

Checks whether the domain has relevant DNS records.

This can identify some nonexistent domains, but DNS failures may be temporary. DNS configuration also does not prove that a particular mailbox exists.

Mailbox verification

Confirms that the user can receive a message at the address.

The most reliable application-level method is sending a time-limited verification link or code.

Deliverability monitoring

Tracks whether messages are accepted, bounced, delayed, blocked, or marked as spam.

Deliverability depends on much more than syntax, including the sender’s reputation and mail configuration.

Anatomy of an Email Address

A typical address has two parts:

john.doe@example.com
  • john.doe is the local part.
  • example.com is the domain.

They are separated by one @ character.

Real email standards support more variation than many developers expect, including quoted local parts, internationalized domains, and—in supported systems—internationalized local parts.

That complexity is why a single “perfect” email regex is rarely the right production solution.

Pattern 1: Minimal Browser-Friendly Check

A common lightweight pattern is:

^[^\s@]+@[^\s@]+\.[^\s@]+$

JavaScript:

const basicEmailPattern =
  /^[^\s@]+@[^\s@]+\.[^\s@]+$/u;

function hasBasicEmailShape(value) {
  return basicEmailPattern.test(value);
}

It checks for:

  • One or more non-whitespace characters before @
  • One or more non-whitespace characters after @
  • A period somewhere in the domain
  • Additional non-whitespace characters after that period

Examples:

hasBasicEmailShape("user@example.com");
// true

hasBasicEmailShape("user.name+news@example.co.uk");
// true

hasBasicEmailShape("userexample.com");
// false

hasBasicEmailShape("user @example.com");
// false

Advantages

  • Easy to understand
  • Fast
  • Supports plus-addressing
  • Does not assume a fixed top-level-domain length
  • Useful for immediate form feedback

Limitations

It may accept malformed values such as:

user..name@example.com
user@-example.com
user@example..com

Use it as a basic user-interface check—not as proof that the address is valid or deliverable.

Pattern 2: Practical ASCII-Only Check

If your application deliberately accepts only conventional ASCII addresses, validate the local part and domain separately.

Local-part pattern

^[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+)*$

This allows common unquoted local-part characters while preventing:

  • A period at the beginning
  • A period at the end
  • Consecutive periods

Domain pattern

^(?=.{1,253}$)(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)+[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$

This requires dot-separated domain labels and prevents a label from starting or ending with a hyphen.

JavaScript implementation

const localPartPattern =
  /^[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+)*$/;

const domainPattern =
  /^(?=.{1,253}$)(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)+[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$/;

function validateAsciiEmail(input) {
  const value = input.trim();

  if (value.length === 0 || value.length > 254) {
    return false;
  }

  const separator = value.lastIndexOf("@");

  if (separator <= 0) {
    return false;
  }

  const localPart = value.slice(0, separator);
  const domain = value.slice(separator + 1);

  return (
    localPartPattern.test(localPart) &&
    domainPattern.test(domain)
  );
}

Examples:

validateAsciiEmail("john@example.com");
// true

validateAsciiEmail("john.doe+news@example.co.uk");
// true

validateAsciiEmail(".john@example.com");
// false

validateAsciiEmail("john..doe@example.com");
// false

validateAsciiEmail("john@-example.com");
// false

validateAsciiEmail("john@example..com");
// false

Important limitation

This is an application policy, not a complete implementation of every email-address format allowed by internet mail standards.

It intentionally rejects quoted local parts and internationalized local parts. If those must be supported, use a maintained email-validation library with explicit internationalization support.

Why the Common Regex Is Flawed

This pattern frequently appears in tutorials:

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

It looks reasonable but can accept:

.user@example.com
user.@example.com
user..name@example.com
user@-example.com
user@example-.com
user@example..com

It can also reject potentially legitimate addresses because it assumes:

  • The local part uses a small ASCII character set
  • The final domain label contains only letters
  • Every acceptable domain follows the same simplified structure

The pattern is acceptable only if these restrictions match a documented application policy and additional checks correct its malformed-domain behavior.

Do not present it as universally correct.

Use the Browser’s Email Input

For web forms, start with the semantic HTML input:

<label for="email">Email address</label>
<input
  id="email"
  name="email"
  type="email"
  autocomplete="email"
  maxlength="254"
  required
>

Browsers provide basic format validation and may display an email-friendly keyboard on mobile devices. The field also communicates its purpose to accessibility and password-management tools.⁠⁠

Client-side validation improves user experience, but it can be bypassed. Always validate again on the server.⁠⁠

Avoid adding a restrictive pattern attribute unless the application intentionally supports a narrower address policy than the browser.

JavaScript Validation Example

Use browser validation for the form and a small function for custom feedback:

const form = document.querySelector("#registration-form");
const emailInput = document.querySelector("#email");
const emailError = document.querySelector("#email-error");

form.addEventListener("submit", event => {
  const email = emailInput.value.trim();

  if (!emailInput.validity.valid) {
    event.preventDefault();
    emailError.textContent =
      "Enter a valid email address.";
    emailInput.focus();
    return;
  }

  emailError.textContent = "";
});

Do not rely on JavaScript alone. A client can submit a request directly to the API without using the form.

PHP Validation Example

PHP includes an email-validation filter:

<?php

$email = trim($_POST['email'] ?? '');

if ($email === '') {
    $error = 'Email is required.';
} elseif (strlen($email) > 254) {
    $error = 'Email is too long.';
} elseif (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
    $error = 'Enter a valid email address.';
} else {
    // Continue to verification.
}

The exact formats accepted by a platform validator may differ from another library. Test the behavior against the address types your application intends to support.

Laravel Validation Example

Laravel provides built-in email validation:

use Illuminate\Http\Request;

public function register(Request $request)
{
    $validated = $request->validate([
        'email' => [
            'required',
            'string',
            'email',
            'max:254',
        ],
    ]);

    // Create the unverified account and send
    // a time-limited verification link.
}

If the address must be unique:

use Illuminate\Validation\Rule;

$validated = $request->validate([
    'email' => [
        'required',
        'string',
        'email',
        'max:254',
        Rule::unique('users', 'email'),
    ],
]);

A uniqueness check should not replace database enforcement. Add an appropriate unique index or constraint after deciding how your application normalizes and compares addresses.

Be careful with case handling. The domain is case-insensitive, but the local part’s theoretical behavior is more complicated. Preserve the original address and define a consistent lookup policy.

Python Validation

Avoid building a complex RFC-style regex with Python’s re module. Use a maintained email-address validation library that supports the requirements of your application.

A typical library-based workflow should:

  1. Parse the address.
  2. Return a normalized form.
  3. Reject unsupported syntax.
  4. Optionally validate domain information.
  5. Preserve the original value when appropriate.
  6. Still require confirmation.

The Python standard library’s message-parsing tools are not automatically strict registration-form validators.

Internationalized Email Addresses

Internationalized domains can contain Unicode characters:

user@مثال.إختبار

Internationalized local parts may also be possible in systems supporting SMTPUTF8:

مستخدم@example.com

SMTPUTF8 extends SMTP for internationalized email addresses.⁠⁠

Supporting these addresses requires more than adding a Unicode flag to a regex. You must consider:

  • Internationalized domain-name conversion
  • Unicode normalization
  • SMTPUTF8 support
  • Mail-provider compatibility
  • Database storage
  • Case handling
  • Downstream integrations
  • Verification-email delivery

Use a maintained library if internationalized email support is required.

Do not advertise internationalized-address support unless the entire delivery pipeline has been tested.

Should You Check DNS?

A DNS check can identify some nonexistent or misconfigured domains, but it is not proof that an address works.

Possible checks include:

  • Whether the domain resolves
  • Whether the domain publishes MX records
  • Whether DNS returns a temporary failure

Use DNS as an additional signal, not as the only acceptance rule.

Be careful because:

  • DNS can temporarily fail.
  • Cached results can become outdated.
  • A domain configuration can change.
  • A domain may accept mail through behavior not captured by a simplistic MX-only check.
  • DNS says nothing about the individual mailbox.

If registration must remain reliable, allow the confirmation email to determine whether the user can receive mail.

Avoid SMTP Mailbox Probing

Some systems attempt to connect to a mail server and ask whether a recipient exists without sending a message.

This is unreliable because mail servers may:

  • Accept every recipient initially
  • Reject verification commands
  • Use catch-all mailboxes
  • Apply greylisting
  • Delay rejection until later
  • Block repeated probes
  • Provide intentionally ambiguous responses

SMTP probing can also create privacy, performance, and reputation concerns.

For most applications, send a normal verification message instead.

The Recommended Verification Flow

A robust registration process looks like this:

  1. Receive the address.
  2. Trim accidental outer whitespace.
  3. Perform server-side syntax validation.
  4. Normalize according to a documented policy.
  5. Store the account as unverified.
  6. Generate a random, single-use token.
  7. Store a hash of the token with an expiry time.
  8. Send a verification link.
  9. Mark the address as verified after the link is used.
  10. Invalidate the token.
  11. Rate-limit resends and verification attempts.

Example response:

{
  "message": "If the address can receive email, a verification message will arrive shortly."
}

Avoid revealing whether an address is already registered when that information could support account enumeration.

OWASP recommends consistent messages and response behavior for account-recovery flows to reduce user enumeration risk.⁠⁠

Normalization Rules

Normalize conservatively.

Usually safe:

  • Remove accidental whitespace before and after form input
  • Normalize the domain according to a tested domain-handling strategy
  • Store a separate normalized value for lookup if required

Potentially unsafe:

  • Removing whitespace from inside the address
  • Removing periods from the local part
  • Removing plus tags
  • Converting every local part to lowercase
  • Applying Gmail-specific behavior to every provider
  • Rewriting an address without preserving the original

For example, these may or may not reach the same mailbox depending on the provider:

john.smith@example.com
johnsmith@example.com
john.smith+news@example.com

Do not assume equivalence globally.

Test Cases for Email Validation

A production validator should have automated positive and negative tests.

Common valid cases

user@example.com
john.doe@example.com
john-doe@example.com
john_doe@example.com
john+newsletter@example.com
user@example.co.uk
user@mail.department.example.com

Common invalid cases

userexample.com
@example.com
user@
user @example.com
user@example com
.user@example.com
user.@example.com
user..name@example.com
user@-example.com
user@example-.com
user@example..com

Boundary cases

Also test:

  • Empty input
  • Leading and trailing whitespace
  • Maximum accepted length
  • One character beyond the limit
  • Very long domain labels
  • Unicode domains
  • Unicode local parts
  • Mixed-case addresses
  • Duplicate registration
  • Temporary DNS failure
  • Verification-token expiry
  • Repeated verification requests

Expected results should match your documented policy, not an arbitrary online regex tester.

Security and Operational Checklist

Before deployment:

  • Validate on the server.
  • Limit input length before expensive processing.
  • Escape user-controlled values in rendered HTML.
  • Use parameterized database queries.
  • Rate-limit registration and resend endpoints.
  • Use random, expiring, single-use verification tokens.
  • Store verification-token hashes rather than raw tokens where practical.
  • Avoid exposing account existence.
  • Do not log verification tokens.
  • Monitor delivery failures and bounce rates.
  • Remove or redact email addresses from logs when they are unnecessary.
  • Comply with privacy and retention requirements.

Regex is only one small part of this workflow.

Which Pattern Should You Use?

Basic contact form

Use the browser’s type="email" and server-side framework validation.

If a JavaScript pattern is necessary for immediate feedback:

^[^\s@]+@[^\s@]+\.[^\s@]+$

Treat it as a basic shape check.

ASCII-only application

Use separate local-part and domain checks or a maintained library. Document that internationalized addresses and quoted local parts are not supported.

International application

Use a maintained validator with explicit internationalized-domain and SMTPUTF8 support. Test the complete email-delivery pipeline.

High-risk or regulated workflow

Use:

  • Maintained server-side validation
  • Confirmation email
  • Rate limiting
  • Strong token handling
  • Audit controls
  • Delivery and bounce monitoring
  • A documented normalization policy

Do not depend on one copied regex.

Frequently Asked Questions

Can regex prove that an email exists?

No. Regex checks text format. Only a verification workflow can demonstrate that a user can receive and act on a message sent to that address.

What is the best email regex?

There is no universal pattern for every email standard and application policy.

For lightweight user-interface feedback:

^[^\s@]+@[^\s@]+\.[^\s@]+$

For production acceptance, use a maintained server-side validator and send a verification email.

Should I validate email on the client or server?

Both, but for different reasons.

Client-side validation improves feedback. Server-side validation enforces the application’s rules because clients can bypass browser checks.

Should the regex require a two-character top-level domain?

No. Avoid assumptions such as:

\.[A-Za-z]{2,4}

Top-level domains can be longer, and internationalized domains require additional handling.

Are plus signs valid?

They are commonly valid and widely used:

user+newsletter@example.com

Do not reject + unless a documented business requirement makes it necessary.

Can DNS confirm that a mailbox exists?

No. DNS describes the domain’s mail configuration, not whether a particular recipient exists.

Final Recommendation

Do not try to solve complete email validation with one enormous regular expression.

Use this layered approach:

  1. Use <input type="email"> for browser forms.
  2. Apply a lightweight client-side format check if needed.
  3. Validate again with a maintained server-side library.
  4. Enforce reasonable length and resource limits.
  5. Normalize conservatively.
  6. Send a time-limited verification link.
  7. Mark the address as verified only after confirmation.
  8. Monitor bounces and delivery failures.

A short, understandable regex combined with server validation and verification is more reliable than a complex pattern that claims to recognize every theoretically valid address.