suit: Email überprüfen mit preg_match

Beitrag lesen

  1. [...] eine Mindestlänge von zwei Zeichen, was ebenfalls unsinnig ist.

Eine Mindestlänge von 1 Zeichen ist übrigens ebenfalls nicht ganz richtig - der local-part darf sogar ein Leerstring sein, dafür muss er allerdings ein Begrenzer einschlossen werden werden ""@example.com - wobei das de facto natürlich dann 2 Zeichen im local-part sind :)

  1. [...] Der Punkt ist ein ganz normales Zeichen in Mailadressen.

Wobei ein Punkt nicht am Anfang oder Ende des local-part vorkommen darf - ebenso sind wiederholungen des Punkts nicht erlaubt - als z.B. foo..bar@example.com geht nicht ".foo"@example.com ist aber möglich, da hier der ungültige Punkt entsprechend maskiert (mit Begrenzern) ist.

  1. Danach dann noch mal ein Punkt sowie zwei bis vier Zeichen a-zA-Z - das ist wiederum falsch, denn als Top-Level-Domain gibt es ebenfalls keinerlei Begrenzung - wenn man die Nachrichten verfolgt, werden gerade beliebig viele neue Domainnamen ausgedacht und registriert, und ".museum" ist schon lange existent. Es gibt eine Längenbeschränkung für Domainnamen: Jedes Einzelteil darf nicht länger als 63 Zeichen sein, es darf nicht mehr als 127 Einzelteile geben, und insgesamt darf die Domain nicht länger als 255 Zeichen sein. Das gilt auch für die Top-Level-Domain.

Dann würden aber immer noch IPv4 und IPv6-Adressen fehlen, da ist nicht nur Einzelteile gibt, die länger als 4 Zeichen sind, sondern eben auch welche mit nur 1 Zeichen (genauer gesagt einer Dezimalziffer) - und natürlich Doppelpunkte bei IPv6-Adressen (inklusive der eckigen Klammern als Bbegrenzer) also z.B. foo@[::1/128]

Insofern ist das Mailvalidieren mit regulärem Ausdruck relativ sinnlos.

Zumindest per Hand mit einem selbstgestrickten Ausdruck, den kann man nicht schnell zusammenzimmern.

Mein Ansatz für die Validierung von Mailadressen war bislang immer: preg_match("/^.+@.+\..+$/", $mail) - das ist simpel genug, dass man es nicht kaputtkriegen kann. Mindestens ein Zeichen vor dem @, mindestens ein Punkt hinter dem @, getrennt durch Zeichen.

Das ist imho zu wenig, da sie Syntaxfehler nicht ausschließt, die gerne mal eingebaut werden - z.B. Leute die mehrere Mail-Adressen aneinanderhängen (kommt hier oft genug vor).

PHP bietet allerdings auch noch eine Alternative: filter_var().

Und falls es damit nicht klappt, weil filter_var() aus irgend einem Grund nicht zur verfügung steht, kann man den PCRE auch direkt aus dem Sourcecode von PHP graben, den PHP für FILTER_VALIDATE_EMAIL verwendet:

/^(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){255,})(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){65,}@)(?:(?:[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E]+)|(?:\x22(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|(?:\x5C[\x00-\x7F]))*\x22))(?:\.(?:(?:[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E]+)|(?:\x22(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|(?:\x5C[\x00-\x7F]))*\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-+[a-z0-9]+)*\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-+[a-z0-9]+)*)|(?:\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){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}))\]))$/iD