4146 Stimmen

Wie kann ich eine E-Mail-Adresse mithilfe eines regulären Ausdrucks überprüfen?

Im Laufe der Jahre habe ich langsam eine regulärer Ausdruck die die Gültigkeit Die meisten E-Mail-Adressen korrekt, vorausgesetzt, sie verwenden keine IP-Adresse als Serverteil.

Ich verwende es in mehreren PHP-Programmen, und es funktioniert die meiste Zeit. Von Zeit zu Zeit werde ich jedoch von jemandem kontaktiert, der Probleme mit einer Website hat, die es verwendet, und ich muss dann einige Anpassungen vornehmen (vor kurzem habe ich festgestellt, dass ich keine vierstelligen Buchstaben zulasse TLDs ).

Was ist der beste reguläre Ausdruck, den Sie haben oder gesehen haben, um E-Mails zu validieren?

Ich habe mehrere Lösungen gesehen, die Funktionen verwenden, die mehrere kürzere Ausdrücke verwenden, aber ich hätte lieber einen langen komplexen Ausdruck in einer einfachen Funktion als mehrere kurze Ausdrücke in einer komplexeren Funktion.

10 Stimmen

Der Regex, der überprüfen kann, ob eine IDNA korrekt formatiert ist, passt nicht in Stackexchange. (die Regeln für die Kanonisierung sind sehr umständlich und eignen sich besonders schlecht für die Regex-Verarbeitung)

13 Stimmen

0 Stimmen

Die Regexe können sein variabel denn in manchen Fällen kann eine E-Mail ein Leerzeichen enthalten, in anderen Fällen darf sie keine Leerzeichen enthalten.

11voto

MichaelRushton Punkte 10482

RFC 5322 Standard:

Erlaubt dot-atom local-part, quoted-string local-part, obsolete (gemischt dot-atom und quoted-string) local-part, domain name domain, (IPv4, IPv6 und IPv4-mapped IPv6 address) domain literal domain und (nested) CFWS.

'/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD'

RFC 5321 Standard:

Erlaubt dot-atom local-part, quoted-string local-part, domain name domain und (IPv4, IPv6 und IPv4-mapped IPv6 address) domain literal domain.

'/^(?!(?>"?(?>\\\[ -~]|[^"])"?){255,})(?!"?(?>\\\[ -~]|[^"]){65,}"?@)(?>([!#-\'*+\/-9=?^-~-]+)(?>\.(?1))*|"(?>[ !#-\[\]-~]|\\\[ -~])*")@(?!.*[^.]{64,})(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>\.(?2)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?3)){7}|(?!(?:.*[a-f0-9][:\]]){8,})((?3)(?>:(?3)){0,6})?::(?4)?))|(?>(?>IPv6:(?>(?3)(?>:(?3)){5}:|(?!(?:.*[a-f0-9]:){6,})(?5)?::(?>((?3)(?>:(?3)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>\.(?6)){3}))\])$/iD'

Grundlegend:

Erlaubt Punkt-Atom-Lokalteil und Domänennamen-Domäne (erfordert mindestens zwei Domänennamen-Bezeichnungen, wobei die TLD auf 2-6 alphabetische Zeichen beschränkt ist).

"/^(?!.{255,})(?!.{65,}@)([!#-'*+\/-9=?^-~-]+)(?>\.(?1))*@(?!.*[^.]{64,})(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?\.){1,126}[a-z]{2,6}$/iD"

1 Stimmen

In welcher Sprache, zum Teufel, ist das? Ich sehe eine /D Flag, und Sie haben es mit einfachen Anführungszeichen zitiert, aber auch Schrägstriche zur Abgrenzung des Musters verwendet? Es ist nicht Perl, und es kann nicht PCRE sein. Ist es also PHP? Ich glaube, das sind die einzigen drei, die eine Rekursion wie (?1) .

1 Stimmen

Es ist in PHP, das PCRE verwendet. Die Schrägstriche werden nur zur Abgrenzung von Sonderzeichen wie Klammern, eckigen Klammern und natürlich Schrägstrichen und einfachen Anführungszeichen verwendet. Das Flag /D soll verhindern, dass am Ende der Zeichenkette ein Zeilenumbruch eingefügt wird, was sonst erlaubt wäre.

11voto

Mac Punkte 2850

Hier ist der PHP-Code, den ich verwende. Ich habe mich für diese Lösung entschieden, ganz nach dem Motto "Falsch positiv ist besser als falsch negativ", wie ein anderer Kommentator hier erklärte y in Bezug auf die Einhaltung der Antwortzeiten und die Verringerung der Serverlast ... es gibt wirklich keinen Grund, Serverressourcen mit einem regulären Ausdruck zu verschwenden, wenn damit die meisten einfachen Benutzerfehler ausgemerzt werden können. Sie können jederzeit eine Test-E-Mail senden, wenn Sie möchten.

function validateEmail($email) {
  return (bool) stripos($email,'@');
}

2 Stimmen

A) Die "Verschwendung von Server-Ressourcen" ist verschwindend gering, aber wenn Sie so geneigt sind, könnten Sie es clientseitig mit JS machen. b) Was ist, wenn Sie eine Registrierungs-E-Mail senden müssen und der Benutzer me@forgotthedotcom eingibt? Ihre "Lösung" schlägt fehl und Sie verlieren einen Benutzer.

2 Stimmen

A) Sich auf eine JS-Validierung zu verlassen, die fehlschlägt, wenn JavaScript deaktiviert ist, klingt auch nicht wie die beste Idee (nur btw)

0 Stimmen

Was meinen Sie mit "falsch positiv"? Ablehnen von E-Mail-Adressen, die Sie nicht hätten ablehnen sollen? Oder das Akzeptieren von E-Mail-Adressen, die Sie nicht hätten akzeptieren sollen?

8voto

Prasad Punkte 1824

Wenn Sie mit der Annahme leerer Werte einverstanden sind (was keine ungültige E-Mail ist) und PHP 5.2+ verwenden, würde ich vorschlagen:

static public function checkEmail($email, $ignore_empty = false) {
    if($ignore_empty && (is_null($email) || $email == ''))
        return true;
    return filter_var($email, FILTER_VALIDATE_EMAIL);
}

1 Stimmen

Was wäre ein Beispiel einer Adresse mit leeren Werten? Bitte antworten Sie mit Bearbeitung (Änderung) Ihrer Antwort , nicht hier in den Kommentaren ( ohne "Bearbeiten:", "Aktualisieren:" oder ähnlich - die Antwort sollte so aussehen, als wäre sie heute geschrieben worden).

8voto

Coder12345 Punkte 3254

Ich verwende eine mehrstufige Validierung. Da es keinen perfekten Weg gibt, eine E-Mail-Adresse zu validieren, kann auch kein perfekter Weg gefunden werden, aber zumindest kann man den Benutzer benachrichtigen, dass er/sie etwas falsch macht - hier ist mein Ansatz:

  1. Ich überprüfe zunächst mit einem sehr einfachen Regex, ob die E-Mail genau ein @-Zeichen enthält und vor oder nach diesem Zeichen nicht leer ist. z. B. /^[^@\s]+@[^@\s]+$/

  2. Wenn die erste Prüfung nicht erfolgreich ist (was bei den meisten Adressen der Fall sein sollte, auch wenn sie nicht perfekt ist), wird der Benutzer gewarnt, dass die E-Mail ungültig ist, und er kann nicht mit der Eingabe fortfahren.

  3. Wenn sie erfolgreich ist, wird sie anhand einer strengeren Regex überprüft, die gültige E-Mails ausschließen könnte. Wenn die Prüfung nicht erfolgreich ist, wird der Benutzer über einen möglichen Fehler gewarnt, darf aber fortfahren. Im Gegensatz zu Schritt (1), bei dem der Benutzer nicht fortfahren darf, weil es sich um einen offensichtlichen Fehler handelt.

Mit anderen Worten, die erste liberale Validierung dient nur dazu, offensichtliche Fehler zu entfernen, und sie wird als "Fehler" behandelt. Die Leute geben eine leere Adresse ein, eine Adresse ohne @-Zeichen und so weiter. Dies sollte als Fehler behandelt werden. Die zweite ist strenger, aber sie wird als "Warnung" behandelt, und der Benutzer darf mit der Eingabe fortfahren, wird aber gewarnt, zumindest zu prüfen, ob er/sie eine gültige Eingabe gemacht hat. Der Schlüssel liegt hier im Fehler-/Warnungsansatz - der Fehler ist etwas, das unter 99,99% der Umstände keine gültige E-Mail sein kann.

Natürlich können Sie einstellen, was die erste Regex liberaler und die zweite strenger macht.

Je nachdem, was Sie brauchen, könnte der oben beschriebene Ansatz für Sie geeignet sein.

0 Stimmen

Technisch gesehen kann eine E-Mail mehr als 1 @ enthalten. Das ist eine erstaunlich seltsame Entdeckung, die ich kürzlich gemacht habe. EG: "very.(),:;<>[]\".VERY.\"very@ \\ \"very\".unusual"@strange.example.com

1 Stimmen

Einverstanden, aber ich habe nie behauptet, dass meine Methode 100%ig sicher ist. Sie funktioniert in den meisten Fällen. Irgendwann muss man realistisch sein und sehr unwahrscheinliche Fälle ausschließen. Die meisten E-Mail-Adressen sind something@something.something. Wenn sich jemand für eine E-Mail-Adresse entscheidet, die die freieste Syntax von allen verwendet, hat er/sie ein echtes Problem mit verschiedenen Server-/Client-Programmen, die solche E-Mails nicht richtig validieren oder zulassen, oder sie funktionieren beim Senden/Empfangen einfach überhaupt nicht. In diesem Fall wäre ein solcher Benutzer gezwungen, eine "Standard"-Syntax zu verwenden, um sicherzustellen, dass sie überall funktioniert.

8voto

Seltsam, dass Sie keine 4-stelligen TLDs zulassen können. Sie verbieten Menschen aus .info y .name und die Längenbegrenzung Anschlag .reisen y .museum aber ja, sie sind weniger verbreitet als 2-stellige TLDs und 3-stellige TLDs.

Sie sollten auch Großbuchstaben zulassen. E-Mail-Systeme normalisieren den lokalen Teil und den Domänenteil.

Für Ihre Regex des Domänenteils darf der Domänenname nicht mit "-" beginnen und nicht mit "-" enden. Der Bindestrich kann nur dazwischen stehen.

Wenn Sie die BIRNE Bibliothek, schauen Sie sich deren Mailfunktion an (ich habe den genauen Namen/die Bibliothek vergessen). Sie können E-Mail-Adressen validieren, indem Sie eine Funktion aufrufen, und diese validiert die E-Mail-Adresse gemäß der Definition in RFC 822 .

3 Stimmen

@Joseph Yee: Ist RFC 822 nicht ein bisschen veraltet?

1 Stimmen

Re kann keine TLDs mit 4 Zeichen zulassen'. : Worauf beziehen Sie sich?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X