paint-brush
Zur Praktikabilität von Regex für die E-Mail-Adressverarbeitungvon@azw
1,796 Lesungen
1,796 Lesungen

Zur Praktikabilität von Regex für die E-Mail-Adressverarbeitung

von Adam Zachary Wasserman12m2023/04/02
Read on Terminal Reader
Read this story w/o Javascript

Zu lang; Lesen

Ein Kollege hat mich kürzlich auf einen Blog-Beitrag hingewiesen: [Über die Sinnlosigkeit der E-Mail-Regex-Validierung] Dieser Artikel wird diese beiden Behauptungen weiter ausbauen, einige mögliche Anwendungsfälle für E-Mail-Regex diskutieren und mit kommentierten „Kochbuch“-Beispielen abschließen Praktischer E-Mail-Regex.
featured image - Zur Praktikabilität von Regex für die E-Mail-Adressverarbeitung
Adam Zachary Wasserman HackerNoon profile picture

Ein Kollege hat mich kürzlich auf einen Blog-Beitrag hingewiesen: „On the Futility of Email Regex Validation“ . Der Kürze halber werde ich es in diesem Artikel als Sinnlosigkeit bezeichnen.


Ich gebe zu, dass die Herausforderung, einen regulären Ausdruck zu schreiben, der erfolgreich identifizieren kann, ob eine Zeichenfolge der RFC 5322-Definition eines Internet-Nachrichtenheaders entspricht, zwar eine unterhaltsame Herausforderung ist, Futility jedoch kein nützlicher Leitfaden für den praktischen Programmierer ist.


Dies liegt daran, dass RFC 5322-Nachrichtenheader mit RFC 5321-Adressliteralen zusammengeführt werden. Das bedeutet vereinfacht ausgedrückt, dass sich eine gültige SMTP-E-Mail-Adresse von dem unterscheidet, was im Allgemeinen einen gültigen Nachrichtenkopf ausmacht.


Dies liegt auch daran, dass es den Leser dazu anregt, sich mit Randfällen zu beschäftigen, die aus Sicht der Standards theoretisch möglich sind, bei denen ich jedoch zeigen werde, dass sie mit verschwindend geringer Wahrscheinlichkeit „in freier Wildbahn“ auftreten.


Dieser Artikel wird diese beiden Behauptungen weiter vertiefen, einige mögliche Anwendungsfälle für E-Mail-Regex diskutieren und mit kommentierten „Kochbuch“-Beispielen für praktische E-Mail-Regex abschließen.

RFC 5321 ersetzt 5322

Die Universalität von SMTP für die Übertragung von E-Mails bedeutet, dass aus praktischen Gründen keine Prüfung der Formatierung von E-Mail-Adressen vollständig ist, ohne den relevanten IETF RFC, nämlich 5321, genau zu lesen.


5322 betrachtet E-Mail-Adressen lediglich als allgemeine Nachrichtenkopfzeilen, für die keine Sonderfallregeln gelten. Dies bedeutet, dass in Klammern eingeschlossene Kommentare auch in einem Domainnamen gültig sind.


Die in Futility referenzierte Testsuite umfasst 10 Tests, die Kommentare oder diakritische Zeichen oder Unicode-Zeichen enthalten, und gibt an, dass 8 davon gültige E-Mail-Adressen darstellen.


Dies ist falsch, da RFC 5321 ausdrücklich besagt, dass die Domänennamenteile von E-Mail-Adressen „ für SMTP-Zwecke darauf beschränkt sind, aus einer Folge von Buchstaben, Ziffern und Bindestrichen aus dem ASCII-Zeichensatz zu bestehen “.


Im Zusammenhang mit der Erstellung eines regulären Ausdrucks kann man kaum genug betonen, wie stark diese Einschränkung die Sache vereinfacht, insbesondere im Hinblick auf die Bestimmung übermäßiger Stringlängen. Die Anmerkung zu den Beispielen wird dies weiter unten verdeutlichen.


Dies impliziert auch einige andere praktische Überlegungen im Zusammenhang mit der Validierung, die wir weiter unten untersuchen werden.

Postfachnamen in freier Wildbahn

Gemäß beiden RFCs lautet der technische Name für den Teil der E-Mail-Adresse links vom „@“-Symbol „Mailbox“. Beide RFCs bieten einen erheblichen Spielraum hinsichtlich der zulässigen Zeichen im Postfachteil.


Die einzige wesentliche praktische Einschränkung besteht darin, dass Anführungszeichen oder Klammern ausgeglichen sein müssen, was in Vanilla Regex eine echte Herausforderung darstellt.


Allerdings sind auch hier reale Mailbox-Implementierungen der Maßstab, den der praktische Programmierer anwenden sollte.


In der Regel missbilligen die Leute, die uns bezahlen, wenn 90 % unserer abrechenbaren Stunden für die Lösung der 10 % der theoretischen Grenzfälle verwendet werden, die im wirklichen Leben möglicherweise überhaupt nicht existieren.


Schauen wir uns die dominierenden E-Mail-Postfachanbieter, Verbraucher und Unternehmen an und überlegen, welche Arten von E-Mail-Adressen sie zulassen.


Für Verbraucher-E-Mails habe ich einige Primärrecherchen durchgeführt und dabei eine Liste von 5.280.739 E-Mail-Adressen verwendet, die von Twitter-Konten durchgesickert sind.


Basierend auf 115 Millionen Twitter-Konten ergibt sich daraus ein Konfidenzniveau von 99 % mit einer Fehlermarge von 0,055 % für die gesamte Twitter-Population, was sehr repräsentativ für die allgemeine Population aller Internet-E-Mail-Adressen wäre. Folgendes habe ich gelernt:


  • 82 % der Adressen enthielten nur alphanumerische ASCII-Zeichen,


  • 15 % enthielten nur ASCII-Alphanumerik und Punkte (ASCII-Punkte), für 97 % aller Adressen,


  • 3 % enthielten nur ASCII-Alphanumerik, Punkte und Bindestriche, also nominell 100 % der E-Mail-Adressen.


Dies sind jedoch gerundete 100 %. Für die Trivia-Liebhaber da draußen habe ich außerdem Folgendes gefunden:


  • 38 Adressen mit Unterstrichen für 0,00072 % der Gesamtzahl


  • 27 mit Pluszeichen für 0,00051 % und


  • 1 Adresse mit Unicode-Zeichen, die 0,00002 % der Gesamtzahl ausmachen.


Der Nettoeffekt besteht darin, dass Sie unter der Annahme, dass E-Mail-Adresspostfächer nur alphanumerische ASCII-Zeichen, Punkte und Bindestriche enthalten, eine Genauigkeit von mehr als 5 9 für Verbraucher-E-Mails erhalten.


Für geschäftliche E-Mails berichtet Datanyze, dass 6.771.269 Unternehmen 91 verschiedene E-Mail-Hosting-Lösungen nutzen. Allerdings gilt die Pareto-Verteilung, und 95,19 % dieser Postfächer werden von nur 10 Dienstanbietern gehostet.

Gmail for Business (34,35 % Marktanteil)

Google erlaubt beim Erstellen eines Postfachs nur ASCII-Buchstaben, Zahlen und Punkte. Beim Empfang von E-Mails wird jedoch das Pluszeichen akzeptiert.

Microsoft Exchange Online (33,60 %)

Erlaubt nur ASCII-Buchstaben, Zahlen und Punkte.

GoDaddy E-Mail-Hosting (14,71 %)

Verwendet Microsoft 365 und erlaubt nur ASCII-Buchstaben, Zahlen und Punkte.

7 zusätzliche Anbieter (12,53 %)

Nicht dokumentiert.


Leider können wir uns nur bei 82 % der Unternehmen sicher sein und wissen nicht, wie viele Postfächer das darstellt. Allerdings wissen wir, dass von den Twitter-E-Mail-Adressen nur 400 von 173.467 Domains mehr als 100 einzelne E-Mail-Postfächer repräsentierten.


Ich glaube, dass die meisten der 99 % der verbleibenden Domains geschäftliche E-Mail-Adressen waren.


Im Hinblick auf Richtlinien zur Benennung von Postfächern auf Server- oder Domänenebene schlage ich vor, dass es sinnvoll ist, diese 237.592 E-Mail-Adressen als repräsentativ für eine Population von 1 Milliarde geschäftlicher E-Mail-Adressen mit einem Konfidenzniveau von 99 % und einer Fehlermarge von 0,25 % anzunehmen Nahezu 3 9, wenn davon ausgegangen wird, dass ein E-Mail-Adresspostfach nur alphanumerische ASCII-Zeichen, Punkte und Bindestriche enthält.

Anwendungsfälle

Lassen Sie uns noch einmal unter Berücksichtigung der Praktikabilität überlegen, unter welchen Umständen wir möglicherweise eine gültige E-Mail-Adresse programmgesteuert identifizieren müssen.

Neues Konto erstellen/Benutzeranmeldungen

In diesem Anwendungsfall versucht ein potenzieller Neukunde, ein Konto zu erstellen. Es gibt zwei übergeordnete Strategien, die wir in Betracht ziehen könnten. Im ersten Fall versuchen wir zu überprüfen, ob die vom neuen Benutzer angegebene E-Mail-Adresse gültig ist, und fahren synchron mit der Kontoerstellung fort.


Es gibt zwei Gründe, warum Sie diesen Ansatz möglicherweise nicht wählen möchten. Der erste Grund besteht darin, dass Sie zwar überprüfen können, ob die E-Mail-Adresse ein gültiges Format hat, diese jedoch möglicherweise nicht existiert.


Der andere Grund ist, dass synchron in jeder Größenordnung ein Warnwort ist, das den pragmatischen Programmierer dazu veranlassen sollte, stattdessen ein Fire-and-Forget-Modell in Betracht zu ziehen, bei dem ein zustandsloses Web-Frontend Formularinformationen an einen Microservice oder eine API übergibt, die dies tut Validieren Sie die E-Mail asynchron, indem Sie einen eindeutigen Link senden, der den Abschluss des Kontoerstellungsprozesses auslöst.

Kontaktformulare

Im Falle eines einfachen Kontaktformulars, wie es häufig zum Herunterladen von Whitepapers verwendet wird, besteht der potenzielle Nachteil der Annahme von Zeichenfolgen, die wie eine gültige E-Mail aussehen, aber keine gültige E-Mail sind, darin, dass Sie die Qualität Ihrer Marketingdatenbank beeinträchtigen, indem Sie diese nicht validieren die E-Mail-Adresse existiert wirklich.


Auch hier ist das Fire-and-Forget-Modell eine bessere Option als die programmgesteuerte Validierung der in ein Formular eingegebenen Zeichenfolge.

Parsen von Referrer-Protokollen und anderen großen Datenmengen.

Dies führt uns zum eigentlichen Anwendungsfall für die programmatische Identifizierung von E-Mail-Adressen im Allgemeinen und Regex im Besonderen: die Anonymisierung oder das Mining großer Teile unstrukturierten Textes.


Ich bin zum ersten Mal auf diesen Anwendungsfall gestoßen, als ich einen Sicherheitsforscher unterstützte, der Referrer-Protokolle in eine Datenbank zur Betrugserkennung hochladen musste. Die Empfehlungsprotokolle enthielten E-Mail-Adressen, die vor dem Verlassen des Walled Garden des Unternehmens anonymisiert werden mussten.


Das waren Dateien mit Hunderten Millionen Zeilen, und es gab Hunderte von Dateien pro Tag. „Zeilen“ können bis zu tausend Zeichen lang sein.


Das Durchlaufen der Zeichen in einer Zeile, das Anwenden komplexer Tests (z. B. ist dies das erste Vorkommen von @ in der Zeile und ist es Teil eines Dateinamens wie [email protected] ?) unter Verwendung von Schleifen und Standardzeichenfolgenfunktionen hätte erstellt eine zeitliche Komplexität, die unvorstellbar groß war.


Tatsächlich hatte das interne Entwicklungsteam dieses (sehr großen) Unternehmens dies für eine unmögliche Aufgabe erklärt.


Ich habe den folgenden kompilierten regulären Ausdruck geschrieben:

search_pattern = re.compile("[a-zA-Z0-9\!\#\$\%\'\*\+\-\^\_\`\{\|\}\~\.]+@|\%40(?!(\w+\.)**(jpg|png))(([\w\-]+\.)+([\w\-]+)))")


Und habe es in das folgende Python-Listenverständnis eingefügt:

results = [(re.sub(search_pattern, "[email protected]", line)) for line in file]


Ich kann mich nicht erinnern, wie schnell es war, aber es war schnell. Mein Freund konnte es auf einem Laptop ausführen und war in wenigen Minuten fertig. Es war genau. Wir haben einen Wert von 5:9 gemessen und dabei sowohl falsch-negative als auch falsch-positive Ergebnisse untersucht.


Die Tatsache, dass es Referrer-Protokolle gibt, hat mir die Arbeit etwas erleichtert. Sie durften nur „zulässige“ URL-Zeichen enthalten, sodass ich alle Kollisionen abbilden konnte, die ich in der Repo- Readme-Datei dokumentiert habe.


Außerdem hätte ich es noch einfacher (und schneller) machen können, wenn ich die E-Mail-Adressanalyse durchgeführt und mit Gewissheit erfahren hätte, dass alles, was nötig war, um zum Ziel der 5 9 zu gelangen, ASCII-Alphanumerik, Punkte und Bindestriche waren.


Nichtsdestotrotz ist dies ein gutes Beispiel für die Praktikabilität und die Anpassung des Lösungsumfangs an das tatsächlich zu lösende Problem.


Eines der größten Zitate in der gesamten Programmiergeschichte ist die Ermahnung des großen Ward Cunningham, sich eine Sekunde Zeit zu nehmen, um sich genau daran zu erinnern, was man erreichen möchte, und sich dann zu fragen: „Was ist das Einfachste, was möglicherweise funktionieren könnte?“


Für den Anwendungsfall, eine E-Mail-Adresse aus einer großen Menge unstrukturiertem Text zu analysieren (und optional umzuwandeln), war diese Lösung definitiv die einfachste, die ich mir vorstellen konnte.

Kommentiertes Kochbuch

Wie ich eingangs sagte, fand ich die Idee, einen RFC 5322-kompatiblen Regex zu erstellen, amüsant, deshalb zeige ich Ihnen zusammensetzbare Regex-Blöcke, um verschiedene Aspekte des Standards zu behandeln, und erkläre, wie der Regex dies umsetzt. Am Ende zeige ich Ihnen, wie es fertig zusammengebaut aussieht.


Der Aufbau einer E-Mail-Adresse ist:

  1. Das Postfach
  2. Legale Charaktere
  3. Einzelne Punkte (doppelte Punkte sind nicht zulässig)
  4. Gefalteter Leerraum (RFC 5322-Verrücktheit)
  5. (Eine vollständige Regex-Lösung würde auch ausgewogene Klammern und/oder Anführungszeichen enthalten, aber das habe ich noch nicht. Und höchstwahrscheinlich auch nie.)
  6. Das Trennzeichen (@)
  7. Der Domänenname
  8. Analysierbare Standard-DNS-Domänen
  9. IPv4-Adressliterale
  10. IPv6-Adressliterale
  11. IPv6-voll
  12. IPv6-comp (für komprimiert)
  13. 1. Form (2+ 16-Bit-Gruppen mit Nullen in der Mitte)
  14. 2. Form (2+ 16-Bit-Gruppen von Null am Anfang)
  15. 3. Form (2 16-Bit-Gruppen mit Nullen am Ende)
  16. 4. Form (8 16-Bit-Nullgruppen)
  17. IPv6v4-voll
  18. IPv6v4-comp (komprimiert)
  19. 1. Form
  20. 2. Form
  21. 3. Form
  22. 4. Klasse

Nun zum regulären Ausdruck.

Briefkasten

^(?<mailbox>(\[a-zA-Z0-9\\+\\!\\#\\$\\%\\&\\'\\\*\\-\\/\\=\\?\\+\\\_\\\{\\}\\|\\\~]|(?<singleDot>(?<!\\.)(?<!^)\\.(?!\\.))|(?<foldedWhiteSpace>\\s?\\&\\#13\\;\\&\\#10\\;.))\{1,64})


Zuerst haben wir ^ , das das erste Zeichen am Anfang der Zeichenfolge „verankert“. Dies ist zu verwenden, wenn eine Zeichenfolge validiert wird, die nur eine gültige E-Mail enthalten soll. Es stellt sicher, dass das erste Zeichen zulässig ist.


Wenn der Anwendungsfall stattdessen darin besteht, eine E-Mail in einer längeren Zeichenfolge zu finden, lassen Sie den Anker weg.


Als nächstes haben wir (?<mailbox> . Damit wird die Erfassungsgruppe der Einfachheit halber benannt. Innerhalb der erfassten Gruppe befinden sich die drei Regex-Blöcke, getrennt durch das alternative Übereinstimmungssymbol | was bedeutet, dass ein Zeichen mit jedem der drei Ausdrücke übereinstimmen kann.


Ein Teil des Schreibens einer guten (leistungsfähigen und vorhersehbaren) Regex besteht darin, sicherzustellen, dass sich die drei Ausdrücke gegenseitig ausschließen. Das heißt, dass ein Teilstring, der mit einem übereinstimmt, definitiv mit keinem der anderen beiden übereinstimmt. Dazu verwenden wir bestimmte Zeichenklassen anstelle des gefürchteten .* .

Bedingungslos legale Charaktere

[a-zA-Z0-9\+\!\#\$\%\&\'\*\-\/\=\?\+\_\{\}\|\~]

Die erste alternative Übereinstimmung ist eine in eckige Klammern eingeschlossene Zeichenklasse, die alle ASCII-Zeichen erfasst, die in einem E-Mail-Postfach zulässig sind, mit Ausnahme des Punkts, des „gefalteten Leerzeichens“, des doppelten Anführungszeichens und der Klammer.


Der Grund, warum wir sie ausgeschlossen haben, liegt darin, dass sie nur bedingt legal sind, das heißt, dass es Regeln für ihre Verwendung gibt, die validiert werden müssen. Wir kümmern uns um sie in den nächsten beiden Alternativspielen.

singleDot

(?<singleDot>(?<!\.)(?<!^)\.(?!\.))

Die erste Regel dieser Art betrifft den Punkt (Punkt). In einem Postfach ist der Punkt nur als Trennzeichen zwischen zwei Zeichenfolgen zulässiger Zeichen zulässig, sodass zwei aufeinanderfolgende Punkte nicht zulässig sind.


Um eine Übereinstimmung zu verhindern, wenn zwei aufeinanderfolgende Punkte vorhanden sind, verwenden wir den regulären negativen Lookbehind (?<!\.) , der angibt, dass das nächste Zeichen (ein Punkt) nicht übereinstimmt, wenn davor ein Punkt steht.


Regex-Look-Arounds können verkettet werden. Bevor wir zum Punkt (?!^) kommen, gibt es noch einen weiteren negativen Aspekt, der die Regel erzwingt, dass der Punkt nicht das erste Zeichen der Mailbox sein darf.


Nach dem Punkt gibt es einen negativen Look_ahead_ _(?!\.)_ , der verhindert, dass ein Punkt gefunden wird, wenn ihm unmittelbar ein Punkt folgt.

gefaltetWhiteSpace

(?<foldedWhiteSpace>\s?\&\#13\;\&\#10\;.)

Das ist irgendein RFC 5322-Unsinn über das Zulassen von mehrzeiligen Headern in Nachrichten. Ich wette, dass es in der Geschichte der E-Mail-Adressen noch nie jemanden gegeben hat, der ernsthaft eine Adresse mit einem mehrzeiligen Postfach erstellt hat (vielleicht war es ein Scherz).


Aber ich spiele das 5322-Spiel, also hier ist sie, die Zeichenfolge aus Unicode-Zeichen, die den gefalteten Leerraum als alternative Übereinstimmung erstellt.

Ausgewogene doppelte Anführungszeichen und Klammern

Beide RFCs erlauben die Verwendung von doppelten Anführungszeichen als Möglichkeit, Zeichen einzuschließen (oder zu maskieren ), die normalerweise illegal wären.


Sie ermöglichen auch das Einschließen von Kommentaren in Klammern, sodass sie für Menschen lesbar sind, vom Mail Transfer Agent (MTA) jedoch bei der Interpretation der Adresse nicht berücksichtigt werden.


In beiden Fällen sind die Charaktere nur dann legal, wenn sie ausgewogen sind . Das bedeutet, dass es ein Zeichenpaar geben muss, eines zum Öffnen und eines zum Schließen .


Ich bin versucht zu schreiben, dass ich ein Demonstrationem mirabilem entdeckt habe, aber das funktioniert wahrscheinlich erst posthum. Die Wahrheit ist, dass dies in Vanilla Regex nicht trivial ist.


Ich habe die Ahnung, dass die rekursive Natur der „gierigen“ Regex vorteilhaft ausgenutzt werden könnte, allerdings werde ich in den nächsten Jahren wahrscheinlich nicht die nötige Zeit aufwenden, um dieses Problem anzugehen, und so lasse ich es in bester Tradition dabei als Übung für den Leser.

Postfachlänge

{1,64}

Was tatsächlich zählt , ist die maximale Länge eines Postfachs: 64 Zeichen.


Nachdem wir also die Postfacherfassungsgruppe mit einer abschließenden schließenden Klammer geschlossen haben, verwenden wir einen Quantifizierer zwischen geschweiften Klammern, um anzugeben, dass wir mit jedem unserer Alternativen mindestens einmal und höchstens 64 Mal übereinstimmen müssen.

atSign

\s?(?<atSign>(?<!\-)(?<!\.)\@(?!\@))

Der Trennzeichenblock beginnt mit dem Sonderfall \s? denn laut Futility ist ein Leerzeichen direkt vor dem Trennzeichen zulässig, und ich vertraue ihnen nur beim Wort.


Der Rest der Capture-Gruppe folgt einem ähnlichen Muster wie singleDot ; Es stimmt nicht überein, wenn davor ein Punkt oder ein Bindestrich steht oder wenn direkt darauf ein weiteres @ folgt.

Domainname

Hier, wie auch im Postfach, haben wir 3 alternative Übereinstimmungen. Und im letzten davon sind weitere 4 alternative Übereinstimmungen enthalten.

Standard-DNS-Parsable

(?<dns>[[:alnum:]]([[:alnum:]\-]{0,63}\.){1,24}[[:alnum:]\-]{1,63}[[:alnum:]])

Dies wird einige der Tests in Futility nicht bestehen, aber wie bereits erwähnt, entspricht es strikt RFC 5321, der das letzte Wort hat.

IPv4

(?<IPv4>\[((?: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]?)\])

Dazu gibt es nicht allzu viel zu sagen. Dies ist ein bekannter und leicht verfügbarer regulärer Ausdruck für IPv4-Adressen.

IPv6

(?<IPv6>(?<IPv6Full>(\[IPv6(\:[0-9a-fA-F]{1,4}){8}\]))|(?<IPv6Comp1>\[IPv6\:((([0-9a-fA-F]{1,4})\:){1,3}(\:([0-9a-fA-F]{1,4})){1,5}?\])|\[IPv6\:((([0-9a-fA-F]{1,4})\:){1,5}(\:([0-9a-fA-F]{1,4})){1,3}?\]))|(?<IPv6Comp2>(\[IPv6\:\:(\:[0-9a-fA-F]{1,4}){1,6}\]))|(?<IPv6Comp3>(\[IPv6\:([0-9a-fA-F]{1,4}\:){1,6}\:\]))|(?<IPv6Comp4>(\[IPv6\:\:\:)\])|(?<IPv6v4Full>(\[IPv6(\:[0-9a-fA-F]{1,4}){6}\:((?: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]?)\])|(?<IPv6v4Comp1>\[IPv6\:((([0-9a-fA-F]{1,4})\:){1,3}(\:([0-9a-fA-F]{1,4})){1,5}?(\:((?: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]?))\])|\[IPv6\:((([0-9a-fA-F]{1,4})\:){1,5}(\:([0-9a-fA-F]{1,4})){1,3}?(\:((?: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]?))\]))|(?<IPv6v4Comp2>(\[IPv6\:\:(\:[0-9a-fA-F]{1,4}){1,5}(\:((?: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]?))\]))|(?<IPv6v4Comp3>(\[IPv6\:([0-9a-fA-F]{1,4}\:){1,5}\:(((?: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]?))\]))|(?<IPv6v4Comp4>(\[IPv6\:\:\:((?: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]?)\]))


Ich konnte keinen guten regulären Ausdruck für IPv6- (und IPv6v4-)Adressen finden, also habe ich meinen eigenen geschrieben und mich dabei sorgfältig an die von Backus/Naur notierten Regeln aus RFC 5321 gehalten.


Ich werde nicht jede Untergruppe des IPv6-Regex mit Anmerkungen versehen, aber ich habe jede Untergruppe benannt, um es einfacher zu machen, sie auseinanderzunehmen und zu sehen, was vor sich geht.


Eigentlich nichts allzu Interessantes, außer vielleicht die Art und Weise, wie ich Greedy Matching auf der „linken“ Seite und Non-Greedy auf der „rechten“ Seite in der IUPv6Comp1-Erfassungsgruppe kombiniert habe.

Der volle Monty

Ich habe den endgültigen regulären Ausdruck zusammen mit den Testdaten von Futility gespeichert und durch einige meiner eigenen IPv6-Testfälle in Regex101 erweitert. Ich hoffe, dass Ihnen dieser Artikel gefallen hat und dass er sich für viele von Ihnen als nützlich und zeitsparend erweist.


AZW