E-Mail-Regex: E-Mail-Adresse in JavaScript, PHP und HTML prüfen

Eine E-Mail-Regex zum Kopieren, an echten Fällen getestet, mit der JavaScript-Funktion, dem PHP-Pendant und dem HTML-Attribut: was sie prüft, was sie durchlässt und wie du weiter gehst.

E-Mail-Regex: E-Mail-Adresse in JavaScript und PHP prüfen
Schnelle Antwort

Um das Format einer E-Mail-Adresse zu prüfen, testest du sie mit der Regex unten (test() in JavaScript, preg_match() in PHP). Sie akzeptiert prenom.nom+tag@sous.domaine.fr und lehnt doppelte Punkte, Leerzeichen und Domains ohne Endung ab. Dass das Postfach existiert, garantiert sie nicht: Dafür musst du eine Nachricht senden oder die Domain abfragen.

Eine E-Mail-Regex macht genau eine Sache: Sie prüft, ob eine Zeichenkette die Form einer E-Mail-Adresse hat. Das ist wenig, und es ist in jedem Registrierungs-, Kontakt- oder Bestellformular unverzichtbar. Hier ist der reguläre Ausdruck, den ich seit Jahren einsetze, mit seinen Fassungen für JavaScript, PHP und HTML – und vor allem mit dem Detail, was er akzeptiert und was er ablehnt.

Die E-Mail-Regex zum Kopieren

javascript
^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$

Von links nach rechts gelesen:

  • ^ und $: Die gesamte Zeichenkette muss eine Adresse sein, nicht bloß eine enthalten.
  • [^<>()[\]\\.,;:\s@"]+: Der lokale Teil (vor dem @) besteht aus erlaubten Zeichen, ohne Leerzeichen und ohne reservierte Satzzeichen. Durch einen Punkt getrennte Gruppen (prenom.nom) sind erlaubt, ein doppelter Punkt nicht.
  • |(".+"): Die von der Norm vorgesehene Alternative in Anführungszeichen erlaubt "jean dupont"@example.com.
  • @, dann die Domain: entweder eine IP-Adresse in eckigen Klammern ([192.168.1.1]) oder alphanumerische Labels, durch Punkte getrennt und mit einer Endung aus mindestens zwei Buchstaben abgeschlossen.
Historie

Diese Regel hat im Oktober 2022 eine Fassung ersetzt, in der bei der Migration der Website 2021 die Backslashes verschwunden waren. Wenn du die alte kopiert hattest, tausche sie aus: Sie ließ fehlerhafte Adressen durch.

Was die Regex prüft und was nicht

Die folgende Tabelle zeigt das tatsächliche Ergebnis von test() unter Node.js 22 und von preg_match() unter PHP 8.5 für sechzehn Adressen. Beide Engines urteilen gleich.

Getestete Adresse Ergebnis Warum
jean.dupont@example.com akzeptiert der Standardfall
jean+news@sub.example.co.uk akzeptiert das + und Subdomains sind legitim
JEAN@EXAMPLE.COM akzeptiert das Flag i ignoriert die Groß- und Kleinschreibung
"jean dupont"@example.com akzeptiert lokaler Teil in Anführungszeichen, von RFC 5322 vorgesehen
jean@[192.168.1.1] akzeptiert Domain als IP-Adresse
jéan@exemple.fr akzeptiert der lokale Teil akzeptiert Nicht-ASCII-Zeichen
jean@localhost abgelehnt keine Endung nach dem Punkt
jean@example abgelehnt derselbe Grund
jean..dupont@example.com abgelehnt doppelter Punkt im lokalen Teil
jean@exa_mple.com abgelehnt der Unterstrich ist in einem Domainnamen nicht erlaubt
jean@exemple.café abgelehnt Endung mit Akzent: siehe Grenzen
a@b.c abgelehnt Endung aus einem einzigen Buchstaben
@example.com abgelehnt lokaler Teil leer
jean@.com abgelehnt Domain vor der Endung leer
jean dupont@example.com abgelehnt Leerzeichen
jean@example.com (Leerzeichen am Ende) abgelehnt der Anker $ lehnt jedes Zeichen nach der Endung ab: denk an trim()

Was keine Regex prüfen kann: ob die Domain existiert, ob sie Post annimmt und ob das Postfach aktiv ist. personne@gmail.com hat eine perfekte Form und empfängt vermutlich nichts.

JavaScript-Fassung

Die Funktion nimmt die Adresse als Parameter, entfernt die Leerzeichen davor und danach und gibt true oder false zurück. Das Flag i macht den Vergleich unabhängig von der Groß- und Kleinschreibung.

validateEmail.js
/**
 * Prüft das Format einer E-Mail-Adresse.
 * @param {string} email
 * @returns {boolean}
 */
function validateEmail(email) {
  const emailReg = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/i;
  return emailReg.test(String(email).trim());
}

console.log(validateEmail('jean.dupont@example.com')); // true
console.log(validateEmail('jean..dupont@example.com')); // false
console.log(validateEmail(' jean@example.com '));      // true, dank trim

Im Formular

Der typische Anwendungsfall: das Absenden blockieren und eine Meldung anzeigen, solange die Adresse falsch aufgebaut ist.

formulaire.js
const form = document.querySelector('#inscription');
const champ = document.querySelector('#email');
const erreur = document.querySelector('#email-erreur');

form.addEventListener('submit', (event) => {
  if (!validateEmail(champ.value)) {
    event.preventDefault();
    erreur.textContent = 'Adresse e-mail invalide';
    champ.setAttribute('aria-invalid', 'true');
    champ.focus();
  }
});

Das Fehlerfeld ist ein sichtbares Element neben dem Eingabefeld, keine alert()-Box: Der Nutzer behält den Kontext und kann sofort korrigieren.

PHP-Fassung

Die Prüfung auf der Clientseite ist eine Eingabehilfe, keine Sicherheitsmaßnahme. Der Server muss die Kontrolle wiederholen: JavaScript lässt sich abschalten, und ein Formular kann direkt aufgerufen werden. Dieselbe Regex funktioniert mit preg_match(), bis auf die Anführungszeichen.

isValidEmail.php
/**
 * Prüft das Format einer E-Mail-Adresse.
 */
function isValidEmail(string $email): bool
{
    $pattern = '/^(([^<>()[\]\\\\.,;:\s@"]+(\.[^<>()[\]\\\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/i';

    return preg_match($pattern, trim($email)) === 1;
}

var_dump(isValidEmail('jean.dupont@example.com')); // bool(true)
var_dump(isValidEmail('jean@localhost'));          // bool(false)

Beachte die doppelte Maskierung der Backslashes in der PHP-Zeichenkette mit einfachen Anführungszeichen: \\\\ im Code ergibt \\ im Muster, was für die Regex-Engine „ein wörtlicher Backslash“ bedeutet.

Regex oder filter_var?

PHP liefert filter_var($email, FILTER_VALIDATE_EMAIL) mit, das die Norm genauer umsetzt. Beide Ansätze taugen; sie entscheiden nur nicht ganz gleich:

Adresse Regex aus dem Artikel filter_var
a@b.c abgelehnt akzeptiert
"jean dupont"@example.com akzeptiert abgelehnt
jéan@exemple.fr akzeptiert ohne FILTER_FLAG_EMAIL_UNICODE abgelehnt, mit akzeptiert
jean+news@sub.example.co.uk akzeptiert akzeptiert

Für ein öffentliches Formular ist filter_var mit dem Unicode-Flag eine gute Standardwahl; die Regex bleibt nützlich, wenn du in JavaScript und in PHP exakt dieselbe Regel willst.

HTML-Fassung

Der Browser kann eine E-Mail bereits prüfen: type="email" verhindert das Absenden des Formulars, wenn das Format nicht stimmt, und zeigt seine eigene Meldung an. Mit dem Attribut pattern lässt sich eine strengere Regel ergänzen, zum Beispiel die aus diesem Artikel.

formulaire.html
<label for="email">Adresse e-mail</label>
<input
  id="email"
  name="email"
  type="email"
  required
  autocomplete="email"
  pattern="(([^<>\(\)\[\]\\.,;:\s@&quot;]+(\.[^<>\(\)\[\]\\.,;:\s@&quot;]+)*)|(&quot;.+&quot;))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))"
  title="Une adresse de la forme prenom.nom@domaine.fr"
>

Vier Details: pattern ist implizit verankert, ^ und $ gehören also nicht hinein; die Anführungszeichen des Musters schreibt man &quot;, damit das Attribut nicht vorzeitig endet; die Browser kompilieren pattern mit dem Flag v, das verlangt, Klammern und eckige Klammern innerhalb einer Zeichenklasse zu maskieren (\(\)\[\]), sonst wird das Muster stillschweigend ignoriert; und die HTML-Validierung umgeht man mit einer Zeile in der Konsole. Sie verbessert die Nutzererfahrung, sie ersetzt nicht die Prüfung auf dem Server.

Grenzfälle, die man kennen sollte

  • Das +: jean+boutique@gmail.com ist eine gültige Adresse, die viele Leute zum Sortieren ihrer Post nutzen. Eine Regex, die sie ablehnt, kostet Anmeldungen.
  • Die langen Endungen: .photography, .paris, .technology gibt es wirklich. Deshalb endet das Muster auf [a-zA-Z]{2,} und nicht auf einer geschlossenen Liste von Endungen.
  • Die Akzente: Der lokale Teil nimmt sie an, die Domain in dieser Regex nicht (internationalisierte Domains werden vor der Auflösung ohnehin als Punycode geschrieben, xn--…).
  • Die Leerzeichen drumherum: Ein Kopieren aus der Tabellenkalkulation hängt oft ein Leerzeichen an. Rufe vor dem Test trim() auf, so wie es die beiden Funktionen oben tun.
  • Die Groß- und Kleinschreibung: Die Domain unterscheidet sie nicht; der lokale Teil täte es theoretisch, aber kein großer Anbieter macht diesen Unterschied. In Kleinbuchstaben zu vergleichen ist das erwartete Verhalten.

Die Regex testen, bevor du sie ausrollst

Ein Testsatz ist mehr wert als eine Sichtprüfung. In JavaScript genügt eine Schleife über bekannte Adressen:

test.js
const cas = {
  'jean.dupont@example.com': true,
  'jean+news@sub.example.co.uk': true,
  'jean@localhost': false,
  'jean..dupont@example.com': false,
  'jean dupont@example.com': false,
};

for (const [email, attendu] of Object.entries(cas)) {
  const ok = validateEmail(email) === attendu;
  console.log(`${ok ? 'OK ' : 'KO '} ${email}`);
}

Zum Erkunden eines Musters färbt regex101 jede Gruppe ein und erklärt, was sie erfasst. Wähle den Dialekt ECMAScript für JavaScript und PCRE2 für PHP: Beide akzeptieren diese Regex ohne Änderung.

Weiter gehen: prüfen, ob die Adresse existiert

Wenn die Form stimmt, senken drei zusätzliche Kontrollen die Zahl der falschen Adressen, von der günstigsten bis zur verlässlichsten:

  1. Wegwerf-Domains ablehnen (temporäre Adressen, die angelegt werden, um eine Registrierung zu umgehen), anhand einer gepflegten Liste.
  2. Die MX-Einträge der Domain abfragen, auf dem Server: Eine Domain ohne Mailserver wird nie eine Nachricht empfangen. In PHP antwortet checkdnsrr($domaine, 'MX') in einer Zeile.
  3. Eine Bestätigungs-E-Mail senden, mit einem Link zum Anklicken. Das ist der einzige Beweis, dass jemand dieses Postfach liest, und genau so machen es alle seriösen Dienste.

Die ersten beiden Kontrollen setze ich auf den öffentlichen Formularen von Foliade ein; die dritte bleibt der Maßstab, sobald ein Konto angelegt wird.

Die anderen regulären Ausdrücke zur Validierung

Gleicher Ansatz, andere Formate: ein Datum validieren, eine IP-Adresse, eine Postleitzahl oder ein Passwort.

Häufige Fehler

Die Anker ^ und $ vergessen Ohne sie akzeptiert test() „bonjour jean@example.com merci“, weil irgendwo in der Zeichenkette eine gültige Adresse steht. Die Funktion aus diesem Artikel verankert die Regex an beiden Enden.
Nur auf der Clientseite validieren JavaScript lässt sich abschalten und umgehen. Dieselbe Prüfung muss auf dem Server laufen, hier in PHP, bevor irgendetwas gespeichert oder versendet wird.
Glauben, eine gültige Adresse existiere Die Regex prüft eine Form, kein Postfach. „nimportequoi@gmail.com“ kommt durch. Nur eine Bestätigungs-E-Mail beweist, dass die Adresse Post empfängt.
Legitime Adressen ablehnen Zu strenge Regex-Regeln lehnen das „+“ (jean+newsletter@…) oder neue lange Endungen wie .photography ab. Teste immer mit echten Adressen, bevor du die Regel verschärfst.

JavaScriptPHP

Damien Flandrin Webentwickler seit 2010, Gründer von Gekkode und Email Impact. Jeder Artikel wird vor der Veröffentlichung an einem echten Projekt getestet. Kontakt
Newsletter

Neue Tests, Tutorials und Projekte, per E-Mail.

Reproduzierbare Tests, versionierter Code, datierte Ergebnisse. Niemals Spam.