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.

8voto

TombMedia Punkte 1898

Ich verwende diese überarbeitete Version der Regex des Autors schon seit einer Weile, und sie hat mir nicht allzu viele Überraschungen beschert. Mir ist noch nie ein Apostroph in einer E-Mail begegnet, so dass dies nicht bestätigt werden kann. . Sie validiert Jean+François@anydomain.museum y @... aber kein seltsamer Missbrauch dieser nicht alphanumerischen Zeichen .+@you.com .

(?!^[.+&'_-]*@.*$)(^[_\w\d+&'-]+(\.[_\w\d+&'-]*)*@[\w\d-]+(\.[\w\d-]+)*\.(([\d]{1,3})|([\w]{2,}))$)

Es unterstützt IP-Adressen you@192.168.1.1 aber ich habe es nicht genug verfeinert, um mit gefälschten IP-Adressbereichen wie 999.999.999.1 .

Es unterstützt auch alle TLDs mit mehr als drei Zeichen, die asdf@asdf.asdf Ich glaube, das Original hat das durchgelassen. Ich bin geschlagen worden, es gibt jetzt zu viele TLDs über 3 Zeichen .

Ich weiß, dass der Auftraggeber seine Regex aufgegeben hat, aber dieser Geschmack lebt weiter.

1 Stimmen

Für alle: Der reguläre Ausdruck in der Frage wurde in Revision 10 im Jahr 2015 (etwa 7 Jahre später) entfernt.

1 Stimmen

Ein Strikeout sollte nicht notwendig sein. Dafür ist die Änderungshistorie gedacht. Wenn etwas nicht mehr gültig ist, sollte es entfernt werden. Die Antwort sollte so sein, wie sie heute geschrieben wurde.

8voto

awwright Punkte 530

Der reguläre Ausdruck für eine E-Mail-Adresse lautet:

/^("(?:[!#-\[\]-\u{10FFFF}]|\\[\t -\u{10FFFF}])*"|[!#-'*+\-/-9=?A-Z\^-\u{10FFFF}](?:\.?[!#-'*+\-/-9=?A-Z\^-\u{10FFFF}])*)@([!#-'*+\-/-9=?A-Z\^-\u{10FFFF}](?:\.?[!#-'*+\-/-9=?A-Z\^-\u{10FFFF}])*|\[[!-Z\^-\u{10FFFF}]*\])$/u

Dieser reguläre Ausdruck ist zu 100% identisch mit dem addr-spec ABNF für nicht veraltete E-Mail-Adressen, wie sie in RFC 5321 , RFC 5322 y RFC 6532 .

Außerdem müssen Sie überprüfen:

  • Die E-Mail-Adresse ist wohlgeformt UTF-8 (oder ASCII, wenn Sie nicht an internationalisierte E-Mail-Adressen senden können)
  • Die Adresse ist nicht größer als 320 UTF-8-Bytes
  • Der Benutzerteil (die erste Übereinstimmungsgruppe) ist nicht größer als 64 UTF-8-Bytes
  • Der Domänenteil (die zweite Übereinstimmungsgruppe) ist nicht größer als 255 UTF-8-Bytes

Am einfachsten ist es, eine bestehende Funktion zu verwenden. In PHP können Sie die filter_var Funktion mit FILTER_VALIDATE_EMAIL y FILTER_FLAG_EMAIL_UNICODE (wenn Sie an internationalisierte E-Mail-Adressen senden können):

$email_valid = filter_var($email_input, FILTER_VALIDATE_EMAIL, FILTER_FLAG_EMAIL_UNICODE);

Aber vielleicht bauen Sie ja eine solche Funktion - am einfachsten ist es, einen regulären Ausdruck zu verwenden.

Denken Sie daran, dass damit nur überprüft wird, dass die E-Mail-Adresse keinen Syntaxfehler verursacht. Die einzige Möglichkeit, zu überprüfen, ob die Adresse E-Mails empfangen kann, ist eigentlich eine E-Mail senden.

Als nächstes werde ich behandeln, wie Sie diesen regulären Ausdruck erzeugen.


Ich schreibe eine neue Antwort, weil die meisten Antworten hier den Fehler machen, entweder ein Muster anzugeben, das zu restriktiv ist (und daher nicht gut gealtert ist); oder sie geben einen regulären Ausdruck an, der eigentlich auf einen Header für eine MIME Nachricht, und nicht die E-Mail-Adresse selbst.

Es ist durchaus möglich, einen regulären Ausdruck aus einer ABNF zu bilden, solange es keine rekursiven Teile gibt.

RFC 5322 legt fest, was in einer MIME-Nachricht gesendet werden darf; betrachten Sie dies als Obergrenze für eine legale E-Mail-Adresse.

Es wäre jedoch ein Fehler, diese ABNF genau zu befolgen: Dieses Muster stellt technisch gesehen dar, wie man eine E-Mail-Adresse kodiert in einer MIME-Nachricht und erlaubt Zeichenketten, die nicht Teil der E-Mail-Adresse sind, wie z. B. faltbare Leerzeichen und Kommentare; außerdem werden veraltete Formulare unterstützt, deren Erzeugung nicht legal ist (die aber von Servern aus historischen Gründen gelesen werden). Eine E-Mail-Adresse enthält diese Elemente nicht.

RFC 5322 erklärt:

Sowohl Atom als auch Punkt-Atom werden als eine Einheit interpretiert, die Folgendes umfasst die Zeichenkette, aus der sie bestehen. Semantisch gesehen, sind die optionalen Kommentare und FWS, die den Rest der Zeichen umgeben, nicht Teil des Atoms; das Atom ist nur die Folge von Textzeichen in einem Atom, oder die atext- und "."-Zeichen in einem Punkt-Atom.

In einigen der Definitionen gibt es Nichtterminale, deren Namen mit "obs-" beginnen. Diese "obs-"-Elemente beziehen sich auf Token, die in der veralteten Syntax in Abschnitt 4. In allen Fällen sind diese Produktionen für die Zwecke der Erzeugung legaler Internet Nachrichten zu ignorieren und MÜSSEN NICHT als Teil einer solchen Nachricht verwendet werden.

Wenn Sie die CFWS , BWS y obs-* Regeln aus dem addr-spec in RFC 5322, und führen Sie einige Optimierungen am Ergebnis durch (ich habe "Grünzeug" ), können Sie diesen regulären Ausdruck erzeugen, der mit Schrägstrichen in Anführungszeichen gesetzt und verankert ist (geeignet für die Verwendung in ECMAScript und kompatiblen Dialekten, mit hinzugefügtem Zeilenumbruch zur besseren Übersichtlichkeit):

/^("(?:[!#-\[\]-~]|\\[\t -~])*"|[!#-'*+\-/-9=?A-Z\^-~](?:\.?[!#-'*+\-/-9=?A-Z\^-~])*)
@([!#-'*+\-/-9=?A-Z\^-~](?:\.?[!#-'*+\-/-9=?A-Z\^-~])*|\[[!-Z\^-~]*\])$/

Es werden nur ASCII-E-Mail-Adressen unterstützt. Zur Unterstützung RFC 6532 Internationalisierte E-Mail-Adressen ersetzen Sie die ~ Zeichen mit \u{10FFFF} (PHP, ECMAScript mit dem u Flagge), oder \uFFFF (für UTF-16-Implementierungen, wie .NET und älteres ECMAScript/JavaScript):

/^("(?:[!#-\[\]-\u{10FFFF}]|\\[\t -\u{10FFFF}])*"|[!#-'*+\-/-9=?A-Z\^-\u{10FFFF}](?:\.?[!#-'*+\-/-9=?A-Z\^-\u{10FFFF}])*)@([!#-'*+\-/-9=?A-Z\^-\u{10FFFF}](?:\.?[!#-'*+\-/-9=?A-Z\^-\u{10FFFF}])*|\[[!-Z\^-\u{10FFFF}]*\])$/u

Dies funktioniert, weil die von uns verwendete ABNF nicht rekursiv ist und somit eine nicht rekursive, reguläre Grammatik bildet, die in einen regulären Ausdruck umgewandelt werden kann.

Das sieht folgendermaßen aus:

  • Der Benutzerteil (vor der @ ) kann ein Punkt-Atom oder eine Zeichenkette in Anführungszeichen sein
  • "([!#-\[\]-~]|\\[\t -~])*" gibt die Anführungszeichenform des Benutzers an, z. B. "root@home"@example.com . Es erlaubt jedes Nicht-Steuerzeichen innerhalb von Anführungszeichen, mit der Ausnahme, dass Leerzeichen, Tabulatoren, doppelte Anführungszeichen und umgekehrte Schrägstriche (Backslashes) mit einem Backslash-Escap versehen werden müssen.
  • [!#-'*+\-/-9=?A-Z\^-~] ist das erste Zeichen des Punkt-Atoms des Benutzers.
  • (\.?[!#-'*+\-/-9=?A-Z\^-~])* entspricht dem Rest des Punkt-Atoms und erlaubt Punkte (außer nach einem anderen Punkt oder als letztes Zeichen).
  • @ bezeichnet den Bereich.
  • Der Domänenteil kann ein Punkt-Atom oder ein Domänenliteral sein.
  • [!#-'*+\-/-9=?A-Z\^-~](\.?[!#-'*+\-/-9=?A-Z\^-~])* ist die gleiche Punkt-Atom-Form wie oben, aber hier stehen sie für Domänennamen und IPv4-Adressen.
  • \[[!-Z\^-~]*\] wird mit IPv6-Adressen und zukünftigen Definitionen von Hostnamen übereinstimmen.

Dieser reguläre Ausdruck lässt alle spezifikationskonformen E-Mail-Adressen zu und kann wortwörtlich in einer MIME-Nachricht verwendet werden (mit Ausnahme von Zeilenlängenbegrenzungen, bei denen ein faltbares Leerzeichen hinzugefügt werden muss).

Damit werden auch nicht-einfangende Gruppen so festgelegt, dass match[1] wird der Benutzer sein, match[2] wird der Gastgeber sein. (Wenn jedoch match[1] mit einem doppelten Anführungszeichen beginnt, dann filtern Sie Backslash-Escapes und die doppelten Anführungszeichen am Anfang und Ende heraus: "root"@example.com y root@example.com denselben Posteingang identifizieren).

Schließlich ist zu beachten, dass RFC 5321 setzt Grenzen für die Länge von E-Mail-Adressen. Der Benutzerteil darf bis zu 64 Byte und der Domänenteil bis zu 255 Byte lang sein. Einschließlich des @ Zeichen, beträgt die Grenze für die gesamte Adresse 320 Bytes. Dies wird in Bytes gemessen, nachdem die Adresse UTF-8-kodiert wurde, nicht in Zeichen.

Beachten Sie, dass RFC 5322 ABNF eine zulässige Syntax für Domänennamen definiert, die Namen zulässt, von denen derzeit bekannt ist, dass sie ungültig sind. Dies ermöglicht auch Domänennamen, die in der Zukunft legal werden könnten. Dies sollte kein Problem darstellen, da dies auf die gleiche Weise wie ein nicht existierender Domänenname gehandhabt werden sollte.

Ziehen Sie immer die Möglichkeit in Betracht, dass ein Benutzer eine E-Mail-Adresse eingegeben hat, die funktioniert, auf die er aber keinen Zugriff hat. Der einzige narrensichere Weg, eine E-Mail-Adresse zu überprüfen, ist das Versenden einer E-Mail.

Dies ist eine Anpassung aus meinem Artikel <em><a href="https://fullstack.wiki/mail/address" rel="nofollow noreferrer">E-Mail-Adressen und Syntax </a></em>.

1 Stimmen

Ich kann dies in Javascript verwenden, aber kann es nicht für C# Verwendung formatiert bekommen. Ich habe versucht, es in regex101 Website setzen und es sagt seine ungültig

1 Stimmen

@PostImpatica Wo genau liegt der Fehler? Regex101 erwartet einen regulären Ausdruck, der durch Schrägstriche getrennt ist. Ich weiß nicht, welchen Dialekt C# erwartet. Wenn Ihr Dialekt Schrägstrich-begrenzt ist, müssen Sie die Schrägstriche mit einem Backslash entkommen.

7voto

public bool ValidateEmail(string sEmail)
{
    if (sEmail == null)
    {
        return false;
    }

    int nFirstAT = sEmail.IndexOf('@');
    int nLastAT = sEmail.LastIndexOf('@');

    if ((nFirstAT > 0) && (nLastAT == nFirstAT) && (nFirstAT < (sEmail.Length - 1)))
    {
        return (Regex.IsMatch(sEmail, @"^[a-z|0-9|A-Z]*([_][a-z|0-9|A-Z]+)*([.][a-z|0-9|A-Z]+)*([.][a-z|0-9|A-Z]+)*(([_][a-z|0-9|A-Z]+)*)?@[a-z][a-z|0-9|A-Z]*\.([a-z][a-z|0-9|A-Z]*(\.[a-z][a-z|0-9|A-Z]*)?)$"));
    }
    else
    {
        return false;
    }
}

0 Stimmen

Dies schlägt manchmal fehl; ein Benutzer in einer E-Mail-Adresse kann "@"-Zeichen enthalten, wenn sie in einer Zeichenkette in Anführungszeichen stehen.

7voto

Cees Timmerman Punkte 15076

Ich benutze sie immer noch:

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

Aber mit IPv6 und Unicode, die bald kommen, vielleicht:

^\w[^@\s]*@[^@\s]{2,}$

ist am besten. Google Mail erlaubt bereits fortlaufende Punkte, aber Microsoft Exchange Server 2007 lehnt sie ab.

0 Stimmen

Erlaubt nicht "John Smith"@example.com .

0 Stimmen

Das stimmt, aber wann ist das wirklich nötig?

2 Stimmen

Jedes Mal, wenn eine E-Mail-Adresse ein Leerzeichen enthält?

6voto

Dimitris Andreou Punkte 8678

Ich glaube nicht, dass die von Bortzmeyer aufgestellte Behauptung dass "Die Grammatik (spezifiziert in RFC 5322 ) ist dafür zu kompliziert" (um mit einem regulären Ausdruck behandelt zu werden).

Hier ist die Grammatik (aus 3.4.1. Addr-Spec Spezifikation ):

addr-spec       =   local-part "@" domain
local-part      =   dot-atom / quoted-string / obs-local-part
domain          =   dot-atom / domain-literal / obs-domain
domain-literal  =   [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
dtext           =   %d33-90 /          ; Printable US-ASCII
                    %d94-126 /         ;  characters not including
                    obs-dtext          ;  "[", "]", or "\"

Unter der Annahme, dass dot-atom, quoted-string, obs-local-part, obs-domain selbst reguläre Sprachen sind, ist dies eine sehr einfache Grammatik. Ersetzen Sie einfach local-part und domain in der addr-spec-Produktion durch ihre jeweiligen Produktionen, und Sie haben eine reguläre Sprache, die direkt in einen regulären Ausdruck übersetzt werden kann.

5 Stimmen

Sie sollten sich über CFWS informieren, bevor Sie hier Vermutungen anstellen. Es ist ein Albtraum.

0 Stimmen

CFWS = (1*([FWS] Kommentar) [FWS]) / FWS. Ich sehe jedoch keine Regel, die die Sprache unregelmäßig macht. Sicherlich ist sie kompliziert, aber ein komplizierter regulärer Ausdruck könnte sie dennoch verarbeiten.

3 Stimmen

Damit ist die Frage nicht beantwortet. Es ist eine Antwort auf eine andere Antwort.

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