Im Laufe der Jahre habe ich langsam einen regulären Ausdruck entwickelt , der die meisten E-Mail-Adressen korrekt validiert, vorausgesetzt, sie verwenden keine IP-Adresse als Serverteil.
Ich benutze 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 Site hat, die sie verwendet, und am Ende muss ich einige Anpassungen vornehmen (zuletzt wurde mir klar, dass ich keine 4-Zeichen-TLDs zulasse).
Was ist der beste reguläre Ausdruck, den Sie zum Überprüfen von E-Mails haben oder gesehen haben?
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 anstelle mehrerer kurzer Ausdrücke in einer komplexeren Funktion.
quelle
Antworten:
Der vollständig RFC 822-kompatible Regex ist aufgrund seiner Länge ineffizient und unklar. Glücklicherweise wurde RFC 822 zweimal abgelöst und die aktuelle Spezifikation für E-Mail-Adressen lautet RFC 5322 . RFC 5322 führt zu einem regulären Ausdruck, der verstanden werden kann, wenn er einige Minuten lang untersucht wird, und der für den tatsächlichen Gebrauch effizient genug ist.
Ein RFC 5322-kompatibler regulärer Ausdruck befindet sich oben auf der Seite unter http://emailregex.com/ , verwendet jedoch das im Internet schwebende IP-Adressmuster mit einem Fehler, der einen
00
der vorzeichenlosen Byte-Dezimalwerte in a zulässt Punktgetrennte Adresse, die illegal ist. Der Rest scheint mit der RFC 5322-Grammatik übereinzustimmen und besteht mehrere Tests unter Verwendung vongrep -Po
Domainnamen, IP-Adressen, fehlerhaften und Kontonamen mit und ohne Anführungszeichen.Wenn
00
wir den Fehler im IP-Muster korrigieren , erhalten wir einen funktionierenden und ziemlich schnellen regulären Ausdruck. (Kratzen Sie die gerenderte Version und nicht den Abschlag für den tatsächlichen Code.)oder:
Hier ist ein Diagramm der Finite-State-Maschine für den obigen regulären Ausdruck, das klarer ist als der reguläre Ausdruck selbst
Die komplexeren Muster in Perl und PCRE (Regex-Bibliothek, die z. B. in PHP verwendet wird) können RFC 5322 ohne Probleme korrekt analysieren . Python und C # können das auch, aber sie verwenden eine andere Syntax als die ersten beiden. Wenn Sie jedoch gezwungen sind, eine der vielen weniger leistungsfähigen Mustervergleichssprachen zu verwenden, ist es am besten, einen echten Parser zu verwenden.
Es ist auch wichtig zu verstehen, dass die Validierung gemäß RFC absolut nichts darüber aussagt, ob diese Adresse tatsächlich in der angegebenen Domain vorhanden ist oder ob die Person, die die Adresse eingibt, ihr wahrer Eigentümer ist. Auf diese Weise melden sich andere ständig bei Mailinglisten an. Eine Korrektur, die eine ausgefallenere Art der Validierung erfordert, bei der dieser Adresse eine Nachricht gesendet wird, die ein Bestätigungstoken enthält, das auf derselben Webseite wie die Adresse eingegeben werden soll.
Bestätigungstoken sind der einzige Weg zu wissen, dass Sie die Adresse der Person erhalten haben, die sie eingibt. Aus diesem Grund verwenden die meisten Mailinglisten diesen Mechanismus jetzt, um Anmeldungen zu bestätigen. Schließlich kann jeder etwas ablegen
[email protected]
, und das wird sogar als legal angesehen, aber es ist wahrscheinlich nicht die Person am anderen Ende.Für PHP sollten Sie nicht das unter Validieren einer E-Mail-Adresse mit PHP angegebene Muster verwenden. Der richtige Weg, aus dem ich zitiere:
Das ist nicht besser als alle anderen Nicht-RFC-Muster. Es ist nicht einmal klug genug, um mit RFC 822 umzugehen , geschweige denn mit RFC 5322. Dies ist jedoch der Fall .
Wenn Sie ausgefallen und pedantisch werden möchten, implementieren Sie eine vollständige State Engine . Ein regulärer Ausdruck kann nur als rudimentärer Filter fungieren. Das Problem bei regulären Ausdrücken besteht darin, dass es aus Sicht des Benutzers nur unhöflich und unhöflich ist, jemandem mitzuteilen, dass seine perfekt gültige E-Mail-Adresse ungültig ist (falsch positiv), weil Ihr regulärer Ausdruck damit nicht umgehen kann. Eine State Engine für diesen Zweck kann E-Mail-Adressen, die ansonsten als ungültig gelten würden, sowohl validieren als auch korrigieren, da sie die E-Mail-Adresse gemäß jedem RFC zerlegt. Dies ermöglicht eine möglicherweise angenehmere Erfahrung, wie z
Siehe auch Überprüfen von E-Mail-Adressen , einschließlich der Kommentare. Oder Vergleichen der E-Mail-Adresse zur Überprüfung regulärer Ausdrücke .
Debuggex-Demo
quelle
Sie sollten keine regulären Ausdrücke verwenden, um E-Mail-Adressen zu überprüfen.
Verwenden Sie stattdessen die MailAddress- Klasse wie folgt :
Die
MailAddress
Klasse verwendet einen BNF-Parser, um die Adresse gemäß RFC822 vollständig zu validieren.Wenn Sie die
MailAddress
zur Überprüfung der E-Mail-Adresse verwenden möchten, beachten Sie, dass dieser Ansatz auch den Anzeigenamen-Teil der E-Mail-Adresse akzeptiert und möglicherweise nicht genau das ist, was Sie erreichen möchten. Beispielsweise werden diese Zeichenfolgen als gültige E-Mail-Adressen akzeptiert:In einigen dieser Fälle wird nur der letzte Teil der Zeichenfolgen als Adresse analysiert. der Rest davor ist der Anzeigename. Um eine einfache E-Mail-Adresse ohne Anzeigenamen zu erhalten, können Sie die normalisierte Adresse mit Ihrer ursprünglichen Zeichenfolge vergleichen.
Darüber hinaus wird eine Adresse mit einem Punkt am Ende wie
user@company.
auch von MailAddress akzeptiert.Wenn Sie wirklich einen regulären Ausdruck verwenden möchten, finden Sie hier :
quelle
[email protected]
. Sie dürfen sich nicht auf die E-Mail-Validierung verlassen, um XSS zu verhindern.Diese Frage wird häufig gestellt, aber ich denke, Sie sollten einen Schritt zurücktreten und sich fragen, warum Sie E-Mail-Adressen syntaktisch validieren möchten. Was ist der Vorteil wirklich?
Wenn Sie überprüfen möchten, ob eine E-Mail korrekt ist, haben Sie keine andere Wahl, als eine Bestätigungs-E-Mail zu senden und den Benutzer darauf antworten zu lassen. In vielen Fällen werden Sie haben eine Bestätigungsmail ohnehin aus Sicherheitsgründen oder aus ethischen Gründen (so kann man nicht zB Zeichen jemand bis zu einem Dienst gegen ihren Willen) zu senden.
quelle
me@hotmail
, erhält er offensichtlich keine Bestätigungs-E-Mail und wo sind sie dann? Sie sind nicht mehr auf Ihrer Website und fragen sich, warum sie sich nicht anmelden konnten. Nein, das sind sie nicht - sie haben dich völlig vergessen. Wenn Sie jedoch nur eine grundlegende Überprüfung der Gesundheit mit einem regulären Ausdruck durchführen können, während sie noch bei Ihnen sind, können sie diesen Fehler sofort erkennen und Sie haben einen zufriedenen Benutzer.[email protected]
weisen alle diese Adressen auf einen sehr netbusy Oberbefehlshaber hin. :)Es hängt alles davon ab, wie genau Sie sein möchten. Für meine Zwecke, bei denen ich nur versuche, Dinge wie
bob @ aol.com
(Leerzeichen in E-Mails) odersteve
(überhaupt keine Domain) odermary@aolcom
(kein Zeitraum vor .com) fernzuhalten , verwende ichSicher, es wird mit Dingen übereinstimmen, die keine gültigen E-Mail-Adressen sind, aber es geht darum, häufig auftretende einfache Fehler zu erhalten.
Es gibt eine beliebige Anzahl von Änderungen, die an diesem regulären Ausdruck vorgenommen werden können (und einige sind in den Kommentaren zu dieser Antwort enthalten), aber es ist einfach und leicht zu verstehen und ein guter erster Versuch.
quelle
.
ist enthalten in\S
.mary@aolcom
als dass ich kompletter Müll bin YMMV.@
Zeichen zu kontrollieren :/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/
jsfiddle.net/b9chris/mXB96Es hängt davon ab, was Sie am besten meinen: Wenn Sie über das Abrufen jeder gültigen E-Mail-Adresse sprechen, verwenden Sie Folgendes:
( http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html ) Wenn Sie nach etwas Einfacherem suchen, das aber die meisten gültigen E-Mail-Adressen abfängt, versuchen Sie Folgendes:
EDIT: Über den Link:
quelle
email address
, die fälschlicherweise die zweite durchlaufen, aber von der längeren Regex erfasst werden?[AKTUALISIERT] Ich habe alles, was ich über die Validierung von E-Mail-Adressen weiß, hier zusammengefasst: http://isemail.info , das jetzt nicht nur Probleme mit E-Mail-Adressen validiert, sondern auch diagnostiziert. Ich stimme vielen Kommentaren hier zu, dass die Validierung nur ein Teil der Antwort ist. Siehe meinen Aufsatz unter http://isemail.info/about .
is_email () bleibt meines Wissens der einzige Validator, der Ihnen definitiv sagt, ob eine bestimmte Zeichenfolge eine gültige E-Mail-Adresse ist oder nicht. Ich habe eine neue Version unter http://isemail.info/ hochgeladen.
Ich habe Testfälle von Cal Henderson, Dave Child, Phil Haack, Doug Lovell, RFC5322 und RFC 3696 zusammengestellt. Insgesamt 275 Testadressen. Ich habe all diese Tests gegen alle freien Validatoren durchgeführt, die ich finden konnte.
Ich werde versuchen, diese Seite auf dem neuesten Stand zu halten, wenn Leute ihre Validatoren verbessern. Vielen Dank an Cal, Michael, Dave, Paul und Phil für ihre Hilfe und Zusammenarbeit bei der Zusammenstellung dieser Tests und für die konstruktive Kritik an meinem eigenen Validator .
Die Leute sollten sich insbesondere der Errata gegen RFC 3696 bewusst sein . Drei der kanonischen Beispiele sind tatsächlich ungültige Adressen. Die maximale Länge einer Adresse beträgt 254 oder 256 Zeichen, nicht 320.
quelle
[email protected]
da es bei diesem Code um Validierung und nicht um Interpretation geht. Wenn Sie einen Punycode-Übersetzer hinzufügen möchten, nehme ich gerne eine Pull-Anfrage unter github.com/dominicsayers/isemailGemäß der W3C HTML5-Spezifikation :
Kontext:
quelle
john.doe@localhost
ist gültig. Sicher, in einer realen Anwendung (dh einer Community) möchte ich, dass Ihr Vorschlag * durch +"test...."@gmail.com
ist laut RFC vollkommen gültig und semantisch äquivalent zu[email protected]
.In Perl 5.10 oder höher ist das ganz einfach:
quelle
addrspec
Teils für die Frage wirklich relevant ist. Wenn Sie mehr als das akzeptieren und weiterleiten, obwohl ein anderer Teil des Systems, der nicht bereit ist, vollständige RFC5822-Adressen zu akzeptieren, so ist, als wäre das Schießen Ihr eigener Fuß.ich benutze
Welches ist dasjenige, das in ASP.NET vom RegularExpressionValidator verwendet wird.
quelle
[email protected]
wird abgelehnt.^\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w{2,}([-.]\\w+)*$
[email protected]
was tatsächlich gültig ist (ein Kunde von uns hatte eine ähnliche Adresse). `Ich weiß nicht, was am besten ist, aber dieser ist zumindest richtig, solange die Kommentare der Adressen entfernt und durch Leerzeichen ersetzt werden.
Ernsthaft. Sie sollten eine bereits geschriebene Bibliothek zum Überprüfen von E-Mails verwenden. Der beste Weg ist wahrscheinlich, einfach eine Bestätigungs-E-Mail an diese Adresse zu senden.
quelle
Die E-Mail-Adressen, die ich überprüfen möchte, werden von einer ASP.NET-Webanwendung unter Verwendung des System.Net.Mail-Namespace verwendet, um E-Mails an eine Liste von Personen zu senden. Anstatt einen sehr komplexen regulären Ausdruck zu verwenden, versuche ich einfach, eine MailAddress-Instanz aus der Adresse zu erstellen. Der MailAddress-Construtor löst eine Ausnahme aus, wenn die Adresse nicht richtig gebildet wird. Auf diese Weise weiß ich, dass ich zumindest die E-Mail aus der Tür bekommen kann. Natürlich ist dies eine serverseitige Validierung, aber zumindest benötigen Sie diese trotzdem.
quelle
args.Value
das Feld zu verwenden, anstatt es wietxtEmail.Text
fest codiert zu referenzieren . Letzteres bindet Ihren Validator an die einzelne Steuerelementinstanz, was möglicherweise in Ordnung ist, solange Sie ein einzelnes E-Mail-Feld haben, das jedoch nicht anders empfohlen wird.Schnelle Antwort
Verwenden Sie für die Eingabevalidierung den folgenden regulären Ausdruck:
([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)+
Mit diesem regulären Ausdruck übereinstimmende Adressen:
Die zweite Einschränkung ist eine Einschränkung für RFC 5321/5322.
Aufwändige Antwort
Die Verwendung eines regulären Ausdrucks, der E-Mail-Adressen erkennt, kann in verschiedenen Situationen hilfreich sein: Zum Beispiel zum Scannen nach E-Mail-Adressen in einem Dokument, zum Überprüfen von Benutzereingaben oder als Integritätsbedingung für ein Datenrepository.
Es sollte jedoch beachtet werden, dass es keinen Ersatz für das Senden einer Nachricht an die Adresse gibt, wenn Sie herausfinden möchten, ob sich die Adresse tatsächlich auf ein vorhandenes Postfach bezieht. Wenn Sie nur überprüfen möchten, ob eine Adresse grammatikalisch korrekt ist, können Sie einen regulären Ausdruck verwenden. Beachten Sie jedoch, dass
""@[]
es sich um eine grammatikalisch korrekte E-Mail-Adresse handelt, die sich sicherlich nicht auf ein vorhandenes Postfach bezieht.Die Syntax von E-Mail-Adressen wurde in verschiedenen RFCs definiert , insbesondere in RFC 822 und RFC 5322 . RFC 822 sollte als "ursprünglicher" Standard und RFC 5322 als neuester Standard angesehen werden. Die in RFC 822 definierte Syntax ist die mildeste und nachfolgende Standards haben die Syntax immer weiter eingeschränkt, wobei neuere Systeme oder Dienste veraltete Syntax erkennen, aber niemals erzeugen sollten.
In dieser Antwort verstehe ich unter "E-Mail-Adresse" die
addr-spec
Definition in den RFCs (dh[email protected]
, aber nicht"John Doe"<[email protected]>
, nochsome-group:[email protected],[email protected];
).Es gibt ein Problem bei der Übersetzung der RFC-Syntax in reguläre Ausdrücke: Die Syntax ist nicht regulär! Dies liegt daran, dass optionale Kommentare in E-Mail-Adressen zulässig sind, die unendlich verschachtelt werden können, während die unendliche Verschachtelung nicht durch einen regulären Ausdruck beschrieben werden kann. Um nach Adressen zu suchen oder diese zu validieren, die Kommentare enthalten, benötigen Sie einen Parser oder leistungsfähigere Ausdrücke. (Beachten Sie, dass Sprachen wie Perl Konstrukte haben, um kontextfreie Grammatiken regexartig zu beschreiben.) In dieser Antwort werde ich Kommentare ignorieren und nur die richtigen regulären Ausdrücke berücksichtigen.
Die RFCs definieren Syntaxen für E-Mail-Nachrichten, nicht für E-Mail-Adressen als solche. Adressen können in verschiedenen Kopfzeilenfeldern angezeigt werden und werden hier hauptsächlich definiert. Wenn sie in Kopfzeilenfeldern angezeigt werden, können Adressen (zwischen lexikalischen Token) Leerzeichen, Kommentare und sogar Zeilenumbrüche enthalten. Semantisch hat dies jedoch keine Bedeutung. Durch Entfernen dieses Leerzeichens usw. aus einer Adresse erhalten Sie eine semantisch äquivalente kanonische Darstellung . Damit die kanonische Darstellung
first. last (comment) @ [3.5.7.9]
istfirst.last@[3.5.7.9]
.Unterschiedliche Syntaxen sollten für unterschiedliche Zwecke verwendet werden. Wenn Sie in einem (möglicherweise sehr alten) Dokument nach E-Mail-Adressen suchen möchten, empfiehlt es sich möglicherweise, die in RFC 822 definierte Syntax zu verwenden. Wenn Sie jedoch Benutzereingaben validieren möchten, können Sie die verwenden Syntax wie in RFC 5322 definiert, wahrscheinlich nur kanonische Darstellungen akzeptierend. Sie sollten entscheiden, welche Syntax für Ihren speziellen Fall gilt.
Ich verwende in dieser Antwort POSIX "erweiterte" reguläre Ausdrücke unter der Annahme eines ASCII-kompatiblen Zeichensatzes.
RFC 822
Ich kam zu dem folgenden regulären Ausdruck. Ich lade alle ein, es zu versuchen und zu brechen. Wenn Sie falsch positive oder falsch negative Ergebnisse finden, posten Sie diese bitte in einem Kommentar. Ich werde versuchen, den Ausdruck so schnell wie möglich zu korrigieren.
([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]))*(\\\r)*")(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]))*(\\\r)*"))*@([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]))*(\\\r)*])(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]))*(\\\r)*]))*
Ich glaube, dass es mit RFC 822 einschließlich der Errata voll kompatibel ist . E-Mail-Adressen werden nur in ihrer kanonischen Form erkannt. Eine Regex, die Leerzeichen erkennt (faltet), finden Sie in der folgenden Ableitung.
Die Ableitung zeigt, wie ich zu dem Ausdruck gekommen bin. Ich liste alle relevanten Grammatikregeln aus dem RFC genau so auf, wie sie erscheinen, gefolgt von der entsprechenden Regex. Wenn ein Erratum veröffentlicht wurde, gebe ich einen separaten Ausdruck für die korrigierte Grammatikregel (markiert mit "Erratum") und verwende die aktualisierte Version als Unterausdruck in nachfolgenden regulären Ausdrücken.
Wie in Absatz 3.1.4 angegeben. von RFC 822 kann ein optionaler linearer Leerraum zwischen lexikalischen Token eingefügt werden. Wo zutreffend, habe ich die Ausdrücke erweitert, um diese Regel zu berücksichtigen, und das Ergebnis mit "opt-lwsp" markiert.
RFC 5322
Ich kam zu dem folgenden regulären Ausdruck. Ich lade alle ein, es zu versuchen und zu brechen. Wenn Sie falsch positive oder falsch negative Ergebnisse finden, posten Sie diese bitte in einem Kommentar. Ich werde versuchen, den Ausdruck so schnell wie möglich zu korrigieren.
([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|\[[\t -Z^-~]*])
Ich glaube, es ist voll kompatibel mit RFC 5322 einschließlich der Errata . E-Mail-Adressen werden nur in ihrer kanonischen Form erkannt. Eine Regex, die Leerzeichen erkennt (faltet), finden Sie in der folgenden Ableitung.
Die Ableitung zeigt, wie ich zu dem Ausdruck gekommen bin. Ich liste alle relevanten Grammatikregeln aus dem RFC genau so auf, wie sie erscheinen, gefolgt von der entsprechenden Regex. Für Regeln, die semantisch irrelevante (faltbare) Leerzeichen enthalten, gebe ich einen separaten regulären Ausdruck mit der Bezeichnung "(normalisiert)" an, der dieses Leerzeichen nicht akzeptiert.
Ich habe alle "obs-" Regeln aus dem RFC ignoriert. Dies bedeutet, dass die regulären Ausdrücke nur mit E-Mail-Adressen übereinstimmen, die streng RFC 5322-konform sind. Wenn Sie mit "alten" Adressen übereinstimmen müssen (wie es die lockerere Grammatik einschließlich der "obs-" Regeln tut), können Sie eine der RFC 822-Regexes aus dem vorherigen Absatz verwenden.
Beachten Sie, dass einige Quellen (insbesondere w3c ) behaupten, dass RFC 5322 für den lokalen Teil (dh den Teil vor dem @ -Zeichen) zu streng ist. Dies liegt daran, dass "..", "a..b" und "a". sind keine gültigen Punktatome, während sie als Postfachnamen verwendet werden können. Die RFC jedoch nicht erlauben Ortsteilen wie diese, mit der Ausnahme , dass sie zitiert werden müssen. Also statt
[email protected]
du solltest schreiben"a..b"@example.net
, was semantisch äquivalent ist.Weitere Einschränkungen
SMTP (wie in RFC 5321 definiert ) schränkt den Satz gültiger E-Mail-Adressen (oder tatsächlich: Postfachnamen) weiter ein. Es erscheint vernünftig, diese strengere Grammatik aufzuerlegen, damit die übereinstimmende E-Mail-Adresse tatsächlich zum Senden einer E-Mail verwendet werden kann.
RFC 5321 lässt im Grunde den "lokalen" Teil (dh den Teil vor dem @ -Zeichen) in Ruhe, ist jedoch im Domain-Teil (dh der Teil nach dem @ -Zeichen) strenger. Es erlaubt nur Hostnamen anstelle von Punktatomen und Adressliterale anstelle von Domänenliteralen.
Die in RFC 5321 vorgestellte Grammatik ist zu mild, wenn es sowohl um Hostnamen als auch um IP-Adressen geht. Ich habe mir erlaubt, die fraglichen Regeln zu "korrigieren", indem ich diesen Entwurf und RFC 1034 als Richtlinien verwendet habe. Hier ist der resultierende reguläre Ausdruck.
([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)*|\[((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|IPv6:((((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+)])
Beachten Sie, dass Sie je nach Anwendungsfall möglicherweise kein "General-Address-Literal" in Ihrer Regex zulassen möchten. Beachten Sie auch, dass ich
(?!IPv6:)
im endgültigen regulären Ausdruck einen negativen Lookahead verwendet habe , um zu verhindern, dass der Teil "Allgemeines Adressliteral" mit fehlerhaften IPv6-Adressen übereinstimmt. Einige Regex-Prozessoren unterstützen keine negativen Lookaheads. Entfernen Sie die Teilzeichenfolge|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+
aus dem regulären Ausdruck, wenn Sie den gesamten Teil "Allgemeines Adressliteral" entfernen möchten.Hier ist die Ableitung:
Validierung der Benutzereingaben
Ein häufiger Anwendungsfall ist die Validierung von Benutzereingaben, beispielsweise in einem HTML-Formular. In diesem Fall ist es normalerweise sinnvoll, Adressliterale auszuschließen und mindestens zwei Bezeichnungen im Hostnamen zu verlangen. Ausgehend von dem verbesserten RFC 5321-Regex aus dem vorherigen Abschnitt wäre der resultierende Ausdruck:
([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)+
Ich empfehle nicht, den lokalen Teil weiter einzuschränken, z. B. indem Zeichenfolgen in Anführungszeichen ausgeschlossen werden, da wir nicht wissen, welche Art von Postfachnamen einige Hosts zulassen (wie
"a..b"@example.net
oder sogar"a b"@example.net
).Ich empfehle auch nicht, explizit anhand einer Liste von wörtlichen Domänen der obersten Ebene zu validieren oder sogar Längenbeschränkungen aufzuerlegen (denken Sie daran, wie ".museum" ungültig gemacht wurde
[a-z]{2,4}
), aber wenn Sie müssen:([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?\.)*(net|org|com|info|
usw...)
Stellen Sie sicher, dass Ihre Regex auf dem neuesten Stand ist, wenn Sie sich für eine explizite Domain-Validierung auf oberster Ebene entscheiden.
Weitere Überlegungen
Wenn nur Hostnamen im Domänenteil (nach dem @ -Zeichen) akzeptiert werden, akzeptieren die obigen regulären Ausdrücke nur Beschriftungen mit höchstens 63 Zeichen, wie sie sollten. Sie erzwingen jedoch nicht die Tatsache, dass der gesamte Hostname höchstens 253 Zeichen lang sein darf (einschließlich der Punkte). Obwohl diese Einschränkung streng genommen immer noch regelmäßig ist, ist es nicht möglich, einen regulären Ausdruck zu erstellen, der diese Regel enthält.
Eine weitere Überlegung, insbesondere bei Verwendung der regulären Ausdrücke für die Eingabevalidierung, ist das Feedback an den Benutzer. Wenn ein Benutzer eine falsche Adresse eingibt, wäre es schön, etwas mehr Feedback zu geben als eine einfache "syntaktisch falsche Adresse". Mit "Vanille" -Regexen ist dies nicht möglich.
Diese beiden Überlegungen könnten durch Parsen der Adresse angegangen werden. Die zusätzliche Längenbeschränkung für Hostnamen kann in einigen Fällen auch behoben werden, indem ein zusätzlicher regulärer Ausdruck verwendet wird, der sie überprüft und die Adresse mit beiden Ausdrücken vergleicht.
Keiner der regulären Ausdrücke in dieser Antwort ist für die Leistung optimiert. Wenn die Leistung ein Problem darstellt, sollten Sie prüfen, ob (und wie) der reguläre Ausdruck Ihrer Wahl optimiert werden kann.
quelle
arbitrary-long-email-address-should-be-invalid-arbitrary-long-email-address-should-be-invalid.and-the-second-group-also-should-not-be-so-long-and-the-second-group-also-should-not-be-so-long@example.com
sollte nicht validieren. Ich schlage vor, die "+" Zeichen in der ersten Gruppe (Name vor dem optionalen Punkt) und in der zweiten Gruppe (Name nach den folgenden Punkten) in{1,64}
$emailRegex = '/^([-!#-\'*+\/-9=?A-Z^-~]{1,64}(\.[-!#-\'*+\/-9=?A-Z^-~]{1,64})*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)+$/';
Es gibt viele Beispiele dafür im Internet (und ich denke sogar eines, das den RFC vollständig validiert - aber es ist zehn / hundert Zeilen lang, wenn Speicher dient). Die Leute neigen dazu, sich davon mitreißen zu lassen, solche Dinge zu bestätigen. Warum nicht einfach überprüfen, ob es ein @ und mindestens eines hat? und erfüllt eine einfache Mindestlänge. Es ist trivial, eine gefälschte E-Mail einzugeben und trotzdem mit einem gültigen regulären Ausdruck übereinzustimmen. Ich würde vermuten, dass falsch positive Ergebnisse besser sind als falsch negative.
quelle
Denken Sie bei der Entscheidung, welche Zeichen zulässig sind, bitte an Ihre apostrophierten und getrennten Freunde. Ich habe keine Kontrolle darüber, dass mein Unternehmen meine E-Mail-Adresse unter Verwendung meines Namens aus dem HR-System generiert. Das schließt den Apostroph in meinem Nachnamen ein. Ich kann Ihnen nicht sagen, wie oft ich von der Interaktion mit einer Website ausgeschlossen wurde, weil meine E-Mail-Adresse "ungültig" ist.
quelle
Dieser reguläre Ausdruck stammt aus der Email :: Valid- Bibliothek von Perl . Ich glaube, es ist das genaueste, es passt zu allen 822. Und es basiert auf dem regulären Ausdruck im O'Reilly-Buch:
quelle
Während Sie in PHP schreiben, würde ich Ihnen raten, die integrierte PHP-Validierung für E-Mails zu verwenden.
Wenn Sie eine PHP-Version unter 5.3.6 verwenden, beachten Sie bitte dieses Problem: https://bugs.php.net/bug.php?id=53091
Weitere Informationen zur Funktionsweise dieser integrierten Validierung finden Sie hier: Funktioniert filter_var FILTER_VALIDATE_EMAIL von PHP tatsächlich?
quelle
Cal Henderson (Flickr) hat einen Artikel mit dem Titel Parsing von E-Mail-Adressen in PHP geschrieben und zeigt, wie eine ordnungsgemäße Analyse von RFC (2) 822-kompatiblen E-Mail-Adressen durchgeführt wird. Sie können den Quellcode auch in PHP , Python und Ruby erhalten, der cc-lizenziert ist .
quelle
a@b
das gültig wara@b
gültig ist ... in diesem Fallb
ist die Top-Level-Domain.Ich mache mir nie die Mühe, mit meinem eigenen regulären Ausdruck zu kreieren, denn es besteht die Möglichkeit, dass jemand anderes bereits eine bessere Version entwickelt hat. Ich benutze immer Regexlib , um eine zu finden, die mir gefällt.
quelle
Es gibt keine, die wirklich brauchbar ist.
Ich diskutiere einige Probleme in meiner Antwort auf Gibt es eine PHP-Bibliothek zur Überprüfung der E-Mail-Adresse? wird es auch in Regexp Erkennung der E-Mail-Adresse schwer diskutiert ?
Kurz gesagt, erwarten Sie nicht, dass ein einziger, verwendbarer regulärer Ausdruck einen ordnungsgemäßen Job macht. Und der beste reguläre Ausdruck überprüft die Syntax, nicht die Gültigkeit einer E-Mail ([email protected] ist korrekt, wird aber wahrscheinlich abprallen ...).
quelle
Ein einfacher regulärer Ausdruck, der zumindest keine gültige E-Mail-Adresse ablehnt, ist die Suche nach etwas, gefolgt von einem @ -Zeichen und etwas gefolgt von einem Punkt und mindestens zwei Dingen. Es wird nichts abgelehnt, aber nachdem ich die Spezifikation überprüft habe, kann ich keine E-Mail finden, die gültig und abgelehnt wäre.
email = ~
/.+@[^@]+\.[^@]{2,}$/
quelle
/^[^@]+@[^@]+\.[^@]{2}[^@]*$/
prüft tatsächlich auf 1 @ Zeichen. Ihre Regex lässt aufgrund des. * Am Ende mehrere durch./^[^@]+@[^@]+\.[^@]{2,4}$/
Stellen Sie sicher, dass es mit 2 bis 4 Nicht-@ -Zeichen endet. Wie @Josh betonte, erlaubt es jetzt am Ende ein zusätzliches @. Sie können dies aber auch ändern in:/^[^@]+@[^@]+\.[^a-z-A-Z]{2,4}$/
Da alle Domänen der obersten Ebene aZ-Zeichen sind. Sie können die4
durch5
oder mehr ersetzen, sodass Domain-Namen der obersten Ebene auch in Zukunft länger sein können.Sie können das vom jQuery Validation-Plugin verwendete verwenden:
quelle
a-b'[email protected]
aber war in der Lage, die unangemessenen Variationen zu fangen, wiea-b'[email protected]
unda-b'[email protected]
Die umfassendste Bewertung des besten regulären Ausdrucks zur Validierung einer E-Mail-Adresse finden Sie unter diesem Link. " Vergleichen der E-Mail-Adresse zur Überprüfung regulärer Ausdrücke "
Hier ist der aktuelle Top-Ausdruck zu Referenzzwecken:
quelle
Ganz zu schweigen davon, dass nicht-lateinische (chinesische, arabische, griechische, hebräische, kyrillische usw.) Domainnamen in naher Zukunft zugelassen werden sollen . Jeder hat das E - Mail - Regex verwendet zu ändern, da diese Zeichen sind sicherlich nicht abgedeckt werden
[a-z]/i
noch\w
. Sie werden alle scheitern.Der beste Weg, um die E-Mail-Adresse zu validieren, besteht darin , eine E-Mail an die betreffende Adresse zu senden, um die Adresse zu validieren. Wenn die E-Mail-Adresse Teil der Benutzerauthentifizierung ist (Registrieren / Anmelden / usw.), können Sie sie perfekt mit dem Benutzeraktivierungssystem kombinieren. Dh senden Sie eine E-Mail mit einem Link mit einem eindeutigen Aktivierungsschlüssel an die angegebene E-Mail-Adresse und erlauben Sie die Anmeldung nur, wenn der Benutzer das neu erstellte Konto über den Link in der E-Mail aktiviert hat.
Wenn der Zweck des regulären Ausdrucks nur darin besteht, den Benutzer in der Benutzeroberfläche schnell darüber zu informieren, dass die angegebene E-Mail-Adresse nicht im richtigen Format aussieht, sollten Sie am besten überprüfen, ob sie im Wesentlichen dem folgenden regulären Ausdruck entspricht:
So einfach ist das. Warum um alles in der Welt interessieren Sie sich für die Zeichen, die im Namen und in der Domäne verwendet werden? Es liegt in der Verantwortung des Kunden, eine gültige E-Mail-Adresse einzugeben, nicht die des Servers. Selbst wenn der Client eine syntaktisch gültige E-Mail-Adresse wie eingibt
[email protected]
, garantiert dies nicht, dass es sich um eine legitime E-Mail-Adresse handelt. Niemand Regex kann das abdecken.quelle
spaces
nach dem@.
zB erlaubt .[email protected] com net
Betrachten Sie eine gültige E-Mail unter Verwendung des obigen regulären Ausdrucks, wenn sie ungültig zurückgegeben werden soll.Die HTML5-Spezifikation schlägt einen einfachen regulären Ausdruck für die Überprüfung von E-Mail-Adressen vor:
Dies entspricht absichtlich nicht RFC 5322 .
Die Gesamtlänge könnte auch auf 254 Zeichen pro RFC 3696-Errata 1690 begrenzt werden .
quelle
invalid@emailaddress
. Ich würde Vorsicht und viele Tests empfehlen, bevor Sie es verwenden!Für eine anschauliche Demonstration ist das folgende Monster ziemlich gut, erkennt jedoch immer noch nicht alle syntaktisch gültigen E-Mail-Adressen korrekt: Es erkennt verschachtelte Kommentare mit einer Tiefe von bis zu vier Ebenen.
Dies ist ein Job für einen Parser, aber selbst wenn eine Adresse syntaktisch gültig ist, kann sie möglicherweise nicht geliefert werden. Manchmal muss man auf die Hinterwäldler-Methode zurückgreifen: "Hey, ihr alle, schaut uns zu!"
quelle
Gemäß dem offiziellen Standard RFC 2822 ist eine gültige E-Mail-Regex gültig
Wenn Sie es in Java verwenden möchten, ist es wirklich sehr einfach
quelle
(?:[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])
Hier ist das PHP, das ich benutze. Ich habe diese Lösung im Sinne von "False Positives sind besser als False Negatives" gewählt, wie von einem anderen Kommentator hier erklärt, UND im Hinblick darauf, Ihre Antwortzeit hoch und die Serverlast niedrig zu halten ... es besteht wirklich keine Notwendigkeit, Serverressourcen damit zu verschwenden Ein regulärer Ausdruck, wenn dadurch der einfachste Benutzerfehler beseitigt wird. Sie können dies jederzeit verfolgen, indem Sie eine Test-E-Mail senden, wenn Sie möchten.
quelle
RFC 5322 Standard:
Ermöglicht den lokalen Teil des Punktatoms, den lokalen Teil der angegebenen Zeichenfolge, den veralteten lokalen Teil (gemischte Punktatome und die Zeichenfolge der angegebenen Zeichenfolge), die Domänennamendomäne (die IPv4-, IPv6- und IPv4-zugeordnete IPv6-Adresse) und die Domänenliteraldomäne. und (verschachtelte) CFWS.
RFC 5321 Standard:
Ermöglicht die lokale Literaldomäne "Dot-Atom Local-Part", "Quoted-String Local-Part", "Domain Name Domain" und (IPv4-, IPv6- und IPv4-zugeordnete IPv6-Adresse) Domain.
Basic:
Ermöglicht Punkt-Atom-Domänen für lokale Teile und Domänennamen (erfordert mindestens zwei Domänennamenbezeichnungen, wobei die TLD auf 2-6 alphabetische Zeichen beschränkt ist).
quelle
/D
Flagge, und Sie haben sie mit einfachen Anführungszeichen zitiert, aber auch Schrägstriche verwendet, um das Muster abzugrenzen? Es ist nicht Perl und es kann nicht PCRE sein. Ist es also PHP? Ich glaube, das sind die einzigen drei, die eine Rekursion zulassen(?1)
.Seltsam, dass Sie TLDs mit 4 Zeichen nicht zulassen können. Sie verbieten Personen die Verwendung von .info und .name , und die Längenbeschränkung stoppt .travel und .museum , aber ja, sie sind weniger verbreitet als TLDs mit 2 Zeichen und TLDs mit 3 Zeichen.
Sie sollten auch Alphabete in Großbuchstaben zulassen. E-Mail-Systeme normalisieren den lokalen Teil und den Domain-Teil.
Für Ihre Regex des Domain-Teils kann der Domain-Name nicht mit '-' beginnen und nicht mit '-' enden. Dash kann nur dazwischen bleiben.
Wenn Sie die PEAR-Bibliothek verwendet haben, überprüfen Sie deren E-Mail-Funktion (vergessen Sie den genauen Namen / die Bibliothek). Sie können die E-Mail-Adresse überprüfen, indem Sie eine Funktion aufrufen. Die E-Mail-Adresse wird gemäß der Definition in RFC822 überprüft.
quelle
quelle