RegEx für passende britische Postleitzahlen

185

Ich bin hinter einer Regex her, die eine vollständige komplexe britische Postleitzahl nur innerhalb einer Eingabezeichenfolge validiert. Alle ungewöhnlichen Postleitzahlenformulare müssen ebenso wie üblich abgedeckt sein. Zum Beispiel:

Streichhölzer

  • CW3 9SS
  • SE5 0EG
  • SE50EG
  • se5 0eg
  • WC2H 7LT

Keine Übereinstimmung

  • aWC2H 7LT
  • WC2H 7LTa
  • WC2H

Wie löse ich dieses Problem?

Kieran Benton
quelle
2
@axrwkr das sieht nicht hilfreich aus
Kieran Benton
8
Validierung der britischen Postleitzahl - JavaScript und PHP Ich konnte die akzeptierte Antwort nicht erhalten, um mit gültigen Postleitzahlen übereinzustimmen, aber ich habe diese gefunden und sie stimmt mit gültigen Postleitzahlen überein. Für die clientseitige Validierung kann die JavaScript-Version unverändert verwendet werden. Für die serverseitige Validierung ist das Umschreiben des JavaScript als C # recht einfach. Die Postleitzahl wird sogar neu formatiert, um ein Leerzeichen zu erhalten. Wenn Sie also zusätzlich zur Validierung eine Postleitzahl als W1A1AA eingeben, wird sie in W1A 1AA neu formatiert. Es handelt sich sogar um ungewöhnliche Postleitzahlen in verschiedenen britischen Gebieten.
2
Der angegebene Link funktioniert nicht für die Formate "AA1A 1AA". Referenz: dhl.com.tw/content/dam/downloads/tw/express/forms/…
Anthony Scaife
1
Wenn Sie einfach eine Postleitzahl validieren möchten, bieten wir einen kostenlosen REST-API-Endpunkt für die Validierung (Anmeldung erforderlich) an - developer.alliescomputing.com/postcoder-web-api/address-lookup/…
Stephen Keable
1
Gute Frage. Ich denke, es lohnt sich, eine zentrale Manchester-Postleitzahl wie "M1 3HZ" in Ihre Liste ungewöhnlicher Beispiele aufzunehmen, die übereinstimmen müssen. Vielen Menschen sind die 1-Buchstaben-1-Zahlen-Kombinationen nicht bekannt.
Martin Joiner

Antworten:

207

Ich würde empfehlen, einen Blick auf den britischen Regierungsdatenstandard für Postleitzahlen zu werfen [Link jetzt tot; XML-Archiv , siehe Wikipedia zur Diskussion]. Es gibt eine kurze Beschreibung der Daten und das angehängte XML-Schema enthält einen regulären Ausdruck. Es ist möglicherweise nicht genau das, was Sie wollen, aber es wäre ein guter Ausgangspunkt. Das RegEx unterscheidet sich geringfügig vom XML, da ein P-Zeichen an dritter Stelle im Format A9A 9AA gemäß der angegebenen Definition zulässig ist.

Der von der britischen Regierung gelieferte RegEx war:

([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9][A-Za-z]?))))\s?[0-9][A-Za-z]{2})

Wie in der Wikipedia-Diskussion erwähnt, werden dadurch einige nicht reale Postleitzahlen (z. B. solche, die mit AA, ZY beginnen) zugelassen, und sie bieten einen strengeren Test, den Sie ausprobieren können.

Brian Campbell
quelle
52
Und das reg ex mit einem optionalen Leerraum zwischen den beiden Segmenten (GIR 0AA) | ((([AZ- [QVX]] [0-9] [0-9]?) | (([AZ- [QVX]]) [AZ- [IJZ]] [0-9] [0-9]?) | (([AZ- [QVX]] [0-9] [A-HJKSTUW]) | ([AZ- [QVX]] [ AZ- [IJZ]] [0-9] [ABEHMNPRVWXY])))) \ s? [0-9] [AZ- [CIKMOV]] {2})
gb2d
6
Könnte eine gute Idee sein, den eigentlichen
regulären Ausdruck
7
Beachten Sie, dass dieser Regex für das XML-Schema ist, das sich offensichtlich geringfügig von anderen Regex-
Varianten
6
Ich kann das nicht in JavaScript zum Laufen bringen. Funktioniert es nur mit bestimmten Regex-Engines?
NickG
12
Eigentlich haben sie es geändert: Massendatenübertragung :^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]))))[0-9][A-Za-z]{2})$
wieczorek1990
85

Es sieht so aus, als würden wir verwenden ^(GIR ?0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]([0-9ABEHMNPRV-Y])?)|[0-9][A-HJKPS-UW]) ?[0-9][ABD-HJLNP-UW-Z]{2})$ , eine leicht modifizierte Version der von Minglis oben vorgeschlagenen.

Wir müssen jedoch genau untersuchen, wie die Regeln lauten, da die verschiedenen oben aufgeführten Lösungen offenbar unterschiedliche Regeln für die zulässigen Buchstaben anwenden.

Nach einigen Recherchen haben wir weitere Informationen gefunden. Anscheinend verweist eine Seite auf 'govtalk.gov.uk' auf eine Postleitzahlenspezifikation govtalk-postcodes . Dies verweist auf ein XML-Schema im XML-Schema , das eine 'Pseudo-Regex'-Anweisung der Postleitzahlenregeln enthält.

Wir haben das genommen und ein wenig daran gearbeitet, um uns den folgenden Ausdruck zu geben:

^((GIR &0AA)|((([A-PR-UWYZ][A-HK-Y]?[0-9][0-9]?)|(([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRV-Y]))) &[0-9][ABD-HJLNP-UW-Z]{2}))$

Dies macht Leerzeichen optional, beschränkt Sie jedoch auf ein Leerzeichen (ersetzen Sie das '&' durch '{0,} für unbegrenzte Leerzeichen). Es wird davon ausgegangen, dass der gesamte Text in Großbuchstaben geschrieben sein muss.

Wenn Sie Kleinbuchstaben mit einer beliebigen Anzahl von Leerzeichen zulassen möchten, verwenden Sie:

^(([gG][iI][rR] {0,}0[aA]{2})|((([a-pr-uwyzA-PR-UWYZ][a-hk-yA-HK-Y]?[0-9][0-9]?)|(([a-pr-uwyzA-PR-UWYZ][0-9][a-hjkstuwA-HJKSTUW])|([a-pr-uwyzA-PR-UWYZ][a-hk-yA-HK-Y][0-9][abehmnprv-yABEHMNPRV-Y]))) {0,}[0-9][abd-hjlnp-uw-zABD-HJLNP-UW-Z]{2}))$

Dies gilt nicht für Überseegebiete und erzwingt nur das Format, NICHT die Existenz verschiedener Gebiete. Es basiert auf den folgenden Regeln:

Kann die folgenden Formate akzeptieren:

  • "GIR 0AA"
  • A9 9ZZ
  • A99 9ZZ
  • AB9 9ZZ
  • AB99 9ZZ
  • A9C 9ZZ
  • AD9E 9ZZ

Wo:

  • 9 kann eine beliebige einstellige Zahl sein.
  • A kann ein beliebiger Buchstabe sein, außer Q, V oder X.
  • B kann ein beliebiger Buchstabe sein, außer I, J oder Z.
  • C kann ein beliebiger Buchstabe sein, außer I, L, M, N, O, P, Q, R, V, X, Y oder Z.
  • D kann ein beliebiger Buchstabe sein, außer I, J oder Z.
  • E kann eines von A, B, E, H, M, N, P, R, V, W, X oder Y sein.
  • Z kann ein beliebiger Buchstabe sein, außer C, I, K, M, O oder V.

Die besten Wünsche

Colin

Colin
quelle
2
Tolle Antwort, fügte ich in den Übersee hinzu^(([gG][iI][rR] {0,}0[aA]{2})|(([aA][sS][cC][nN]|[sS][tT][hH][lL]|[tT][dD][cC][uU]|[bB][bB][nN][dD]|[bB][iI][qQ][qQ]|[fF][iI][qQ][qQ]|[pP][cC][rR][nN]|[sS][iI][qQ][qQ]|[iT][kK][cC][aA]) {0,}1[zZ]{2})|((([a-pr-uwyzA-PR-UWYZ][a-hk-yxA-HK-XY]?[0-9][0-9]?)|(([a-pr-uwyzA-PR-UWYZ][0-9][a-hjkstuwA-HJKSTUW])|([a-pr-uwyzA-PR-UWYZ][a-hk-yA-HK-Y][0-9][abehmnprv-yABEHMNPRV-Y]))) {0,}[0-9][abd-hjlnp-uw-zABD-HJLNP-UW-Z]{2}))$
David Bradshaw
Warum {0,}anstelle von *unbegrenzten optionalen Leerzeichen angeben ?
Code Animal
74

Ich habe kürzlich eine Antwort auf diese Frage auf britischen Postleitzahlen für die R-Sprache veröffentlicht . Ich habe festgestellt, dass das Regex-Muster der britischen Regierung falsch ist und nicht richtig funktioniert einige Postleitzahlen validiert werden kann. Leider basieren viele der Antworten hier auf diesem falschen Muster.

Ich werde im Folgenden einige dieser Probleme skizzieren und einen überarbeiteten regulären Ausdruck bereitstellen, der tatsächlich funktioniert.


Hinweis

Meine Antwort (und reguläre Ausdrücke im Allgemeinen):

  • Nur validiert Postleitzahlenformate .
  • Stellt nicht sicher, dass eine Postleitzahl rechtmäßig vorhanden ist .
    • Verwenden Sie dazu eine entsprechende API! Weitere Informationen finden Sie in Bens Antwort .

Wenn Sie sich nicht für den schlechten regulären Ausdruck interessieren und nur zur Antwort springen möchten, scrollen Sie nach unten zum Abschnitt Antwort .

Der schlechte Regex

Die regulären Ausdrücke in diesem Abschnitt sollten nicht verwendet werden.

Dies ist die fehlgeschlagene Regex, die die britische Regierung Entwicklern zur Verfügung gestellt hat (nicht sicher, wie lange dieser Link bestehen wird, aber Sie können ihn in ihrer Dokumentation zur Massendatenübertragung sehen ):

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]))))[0-9][A-Za-z]{2})$

Probleme

Problem 1 - Kopieren / Einfügen

Siehe Regex, der hier verwendet wird .

Wie viele Entwickler wahrscheinlich, kopieren / fügen sie Code (insbesondere reguläre Ausdrücke) ein und fügen sie ein, damit sie funktionieren. Obwohl dies theoretisch großartig ist, schlägt es in diesem speziellen Fall fehl, weil das Kopieren / Einfügen aus diesem Dokument tatsächlich eines der Zeichen (ein Leerzeichen) in ein Zeilenumbruchzeichen ändert, wie unten gezeigt:

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]))))
[0-9][A-Za-z]{2})$

Das erste, was die meisten Entwickler tun, ist, die neue Zeile zu löschen, ohne darüber nachzudenken. Jetzt ordnet der reguläre Ausdruck Postleitzahlen nicht mehr Leerzeichen zu (außer demGIR 0AA Postleitzahl).

Um dieses Problem zu beheben, sollte das Zeilenumbruchzeichen durch das Leerzeichen ersetzt werden:

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$
                                                                                                                                                     ^

Problem 2 - Grenzen

Siehe Regex, der hier verwendet wird .

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$
^^                     ^ ^                                                                                                                                            ^^

Der Postleitzahl-Regex verankert den Regex nicht ordnungsgemäß. Jeder, der diese Regex verwendet, um Postleitzahlen zu validieren, könnte überrascht sein, wenn ein Wert wie fooA11 1AAdurchkommt. Das liegt daran, dass sie den Anfang der ersten Option und das Ende der zweiten Option (unabhängig voneinander) verankert haben, wie im obigen regulären Ausdruck ausgeführt.

Dies bedeutet, dass ^(Position am Zeilenanfang bestätigt) nur für die erste Option funktioniert ([Gg][Ii][Rr] 0[Aa]{2}), sodass die zweite Option alle Zeichenfolgen überprüft, die enden mit einer Postleitzahl (unabhängig davon, was vorher kommt).

In ähnlicher Weise ist die erste Option nicht bis zum Ende der Zeile verankert $, so GIR 0AAfooauch akzeptiert wird.

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]))))[0-9][A-Za-z]{2})$

Um dieses Problem zu beheben, sollten beide Optionen in eine andere Gruppe (oder eine nicht erfassende Gruppe) eingeschlossen und die Anker um diese herum platziert werden:

^(([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2}))$
^^                                                                                                                                                                      ^^

Problem 3 - Falscher Zeichensatz

Siehe Regex, der hier verwendet wird .

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$
                                                                                       ^^

In der Regex fehlt -hier ein Zeichen für eine Reihe von Zeichen. So wie es aussieht, wenn eine Postleitzahl das Format hat ANA NAA(wobei Aein Buchstabe und Neine Zahl steht) und mit etwas anderem als Aoder beginntZ sie fehl.

Das heißt, es wird passen A1A 1AAund Z1A 1AA, aber nicht B1A 1AA.

Um dieses Problem zu beheben, sollte das Zeichen -zwischen Aund Zim jeweiligen Zeichensatz platziert werden:

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$
                                                                                        ^

Problem 4 - Falscher optionaler Zeichensatz

Siehe Regex, der hier verwendet wird .

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$
                                                                                                                                        ^

Ich schwöre, sie haben dieses Ding nicht einmal getestet, bevor sie es im Internet veröffentlicht haben. Sie haben den falschen Zeichensatz optional gemacht. Sie machten [0-9]Option in der vierten Unteroption von Option 2 (Gruppe 9). Dadurch kann der Regex mit falsch formatierten Postleitzahlen wie übereinstimmen AAA 1AA.

Um dieses Problem zu beheben, machen Sie stattdessen die nächste Zeichenklasse optional (und lassen Sie den Satz anschließend [0-9]genau einmal übereinstimmen):

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9][A-Za-z]?)))) [0-9][A-Za-z]{2})$
                                                                                                                                                ^

Problem 5 - Leistung

Die Leistung dieser Regex ist extrem schlecht. Zunächst platzierten sie die am wenigsten wahrscheinliche Musteroption, GIR 0AAdie zu Beginn übereinstimmt . Wie viele Benutzer werden diese Postleitzahl wahrscheinlich im Vergleich zu einer anderen Postleitzahl haben? wahrscheinlich nie? Dies bedeutet, dass bei jeder Verwendung des regulären Ausdrucks diese Option zuerst ausgeschöpft werden muss, bevor mit der nächsten Option fortgefahren werden kann. Um zu sehen, wie sich die Leistung auf die Leistung auswirkt, überprüfen Sie die Anzahl der Schritte, die der ursprüngliche reguläre Ausdruck (35) mit demselben regulären Ausdruck ausgeführt hat, nachdem Sie die Optionen umgedreht haben (22).

Das zweite Problem mit der Leistung ist auf die Struktur des gesamten regulären Ausdrucks zurückzuführen. Es macht keinen Sinn, jede Option zurückzuverfolgen, wenn eine fehlschlägt. Die Struktur des aktuellen regulären Ausdrucks kann erheblich vereinfacht werden. Ich gebe eine Lösung dafür im Abschnitt Antwort .

Problem 6 - Leerzeichen

Siehe Regex, der hier verwendet wird

Dies kann an sich nicht als Problem angesehen werden , gibt jedoch den meisten Entwicklern Anlass zur Sorge. Die Leerzeichen in der Regex sind nicht optional. Dies bedeutet, dass die Benutzer, die ihre Postleitzahlen eingeben, ein Leerzeichen in die Postleitzahl einfügen müssen. Dies ist eine einfache Lösung, indem Sie einfach ?nach den Leerzeichen hinzufügen , um sie optional zu machen. Eine Lösung finden Sie im Abschnitt Antwort .


Antworten

1. Festsetzung des Regex der britischen Regierung

Wenn Sie alle im Abschnitt Probleme beschriebenen Probleme beheben und das Muster vereinfachen, erhalten Sie das folgende, kürzere und präzisere Muster. Wir können auch die meisten Gruppen entfernen, da wir die Postleitzahl als Ganzes validieren (nicht einzelne Teile):

Siehe Regex, der hier verwendet wird

^([A-Za-z][A-Ha-hJ-Yj-y]?[0-9][A-Za-z0-9]? ?[0-9][A-Za-z]{2}|[Gg][Ii][Rr] ?0[Aa]{2})$

Dies kann weiter verkürzt werden, indem alle Bereiche aus einem der Fälle (Groß- oder Kleinschreibung) entfernt und ein Flag verwendet werden, bei dem die Groß- und Kleinschreibung nicht berücksichtigt wird. Hinweis : Einige Sprachen haben keine, verwenden Sie also die längere oben. Jede Sprache implementiert das Flag für Groß- und Kleinschreibung anders.

Siehe Regex, der hier verwendet wird .

^([A-Z][A-HJ-Y]?[0-9][A-Z0-9]? ?[0-9][A-Z]{2}|GIR ?0A{2})$

Kürzere wieder ersetzt [0-9]mit \d(wenn Ihre Regex - Engine unterstützt):

Siehe Regex, der hier verwendet wird .

^([A-Z][A-HJ-Y]?\d[A-Z\d]? ?\d[A-Z]{2}|GIR ?0A{2})$

2. Vereinfachte Muster

Ohne bestimmte alphabetische Zeichen zu gewährleisten, kann Folgendes verwendet werden (beachten Sie die Vereinfachungen ab 1. Die Korrektur des Regex der britischen Regierung wurde auch hier angewendet):

Siehe Regex, der hier verwendet wird .

^([A-Z]{1,2}\d[A-Z\d]? ?\d[A-Z]{2}|GIR ?0A{2})$

Und noch weiter, wenn Sie sich nicht für den Sonderfall interessieren GIR 0AA:

^[A-Z]{1,2}\d[A-Z\d]? ?\d[A-Z]{2}$

3. Komplizierte Muster

Ich würde nicht empfehlen, eine Postleitzahl zu stark zu überprüfen, da zu jedem Zeitpunkt neue Gebiete, Bezirke und Unterbezirke erscheinen können. Was ich möglicherweise vorschlagen werde , ist die zusätzliche Unterstützung für Randfälle. Einige Sonderfälle existieren und werden in diesem Wikipedia-Artikel beschrieben .

Hier sind komplexe reguläre Ausdrücke, die die Unterabschnitte von 3. (3.1, 3.2, 3.3) enthalten.

In Bezug auf die Muster in 1. Festsetzung des Regex der britischen Regierung :

Siehe Regex, der hier verwendet wird

^(([A-Z][A-HJ-Y]?\d[A-Z\d]?|ASCN|STHL|TDCU|BBND|[BFS]IQQ|PCRN|TKCA) ?\d[A-Z]{2}|BFPO ?\d{1,4}|(KY\d|MSR|VG|AI)[ -]?\d{4}|[A-Z]{2} ?\d{2}|GE ?CX|GIR ?0A{2}|SAN ?TA1)$

Und in Bezug auf 2. Vereinfachte Muster :

Siehe Regex, der hier verwendet wird

^(([A-Z]{1,2}\d[A-Z\d]?|ASCN|STHL|TDCU|BBND|[BFS]IQQ|PCRN|TKCA) ?\d[A-Z]{2}|BFPO ?\d{1,4}|(KY\d|MSR|VG|AI)[ -]?\d{4}|[A-Z]{2} ?\d{2}|GE ?CX|GIR ?0A{2}|SAN ?TA1)$

3.1 Britische Überseegebiete

Im Wikipedia-Artikel heißt es derzeit (einige Formate leicht vereinfacht):

  • AI-1111: Anguila
  • ASCN 1ZZ: Ascension Island
  • STHL 1ZZ: Heilige Helena
  • TDCU 1ZZ: Tristan da Cunha
  • BBND 1ZZ: Britisches Territorium des Indischen Ozeans
  • BIQQ 1ZZ: Britisches Antarktisgebiet
  • FIQQ 1ZZ: Falkland Inseln
  • GX11 1ZZ: Gibraltar
  • PCRN 1ZZ: Pitcairninseln
  • SIQQ 1ZZ: Süd-Georgien und die südlichen Sandwich-Inseln
  • TKCA 1ZZ: Turks- und Caicosinseln
  • BFPO 11: Akrotiri und Dhekelia
  • ZZ 11& GE CX: Bermuda (laut diesem Dokument )
  • KY1-1111: Cayman Islands (gemäß diesem Dokument )
  • VG1111: Britische Jungferninseln (gemäß diesem Dokument )
  • MSR 1111: Montserrat (gemäß diesem Dokument )

Ein umfassender Regex, der nur den britischen Überseegebieten entspricht, könnte folgendermaßen aussehen:

Siehe Regex, der hier verwendet wird .

^((ASCN|STHL|TDCU|BBND|[BFS]IQQ|GX\d{2}|PCRN|TKCA) ?\d[A-Z]{2}|(KY\d|MSR|VG|AI)[ -]?\d{4}|(BFPO|[A-Z]{2}) ?\d{2}|GE ?CX)$

3.2 Post der britischen Streitkräfte

Obwohl sie kürzlich geändert wurden, um sie besser an das britische Postleitzahlensystem anzupassen BF#(wobei #eine Zahl steht), gelten sie als optionale alternative Postleitzahlen . Diese Postleitzahlen folgen dem Format von BFPO, gefolgt von 1-4 Ziffern:

Siehe Regex, der hier verwendet wird

^BFPO ?\d{1,4}$

3.3 Santa?

Es gibt noch einen weiteren Sonderfall mit dem Weihnachtsmann (wie in anderen Antworten erwähnt): SAN TA1ist eine gültige Postleitzahl. Eine Regex dafür ist sehr einfach:

^SAN ?TA1$
ctwheels
quelle
4
Die vereinfachten Muster sind eine wirklich gute Option. Ich finde es am besten, mit einem regulären Ausdruck nicht zu restriktiv zu sein, da Sie dann sicherstellen müssen, dass er mit Änderungen aktualisiert wird, oder Sie könnten sehr verärgerte Benutzer haben. Ich bin der Meinung, dass es besser ist, lose mit einer vereinfachten Regex übereinzustimmen, um die offensichtlichen Fehler auszusortieren, und dann weitere Überprüfungen durchzuführen, z. B. eine Adressensuche (oder eine Bestätigungs-E-Mail im Fall einer E-Mail-Regex), um die Gültigkeit zu bestätigen.
James Coyle
2
Hervorragende und gründliche Analyse.
Steve
1
Geniale Antwort auf so vielen Ebenen. Letztendlich habe ich mich für Ihr 2. vereinfachtes Muster entschieden. Da ich tatsächlich eine Datenbank mit allen Postleitzahlen in Großbritannien habe, benötige ich nur einen ersten Durchgang, um festzustellen, ob eine Adresszeichenfolge möglicherweise eine gültige Postleitzahl enthält, sodass ich mich nicht um Fehlalarme kümmere (da die tatsächliche Suche sie ausrotten wird). , aber ich kümmere mich um falsche Negative. Und Geschwindigkeit ist auch wichtig.
John Powell
Es gibt so viele Probleme mit dem britischen Postleitzahlensystem, das offenbar vom Komitee vor dem Computerzeitalter erstellt wurde, aber das Problem der variablen Länge und Leerzeichen ist eines der schädlichsten. Ich habe alle Arten von Horror gesehen, einschließlich des Auffüllens von Postleitzahlen wie E1 5JX bis E1 5JX, dh mit drei Leerzeichen, so dass es gut mit SW18 5HA in Excel übereinstimmt (fügen Sie eine schrecklich unangemessene Software der Wahl zum Verwalten von Adressen ein). Die einzig vernünftige Lösung, IMHO, besteht darin, alle Leerzeichen zu entfernen, sodass die Postleitzahl eine einzelne Zeichenfolge ist, bevor sie sich Elastic, Solr, Postgres usw. nähert
John Powell
45

Es gibt keinen umfassenden regulären Ausdruck für die britische Postleitzahl, mit dem eine Postleitzahl validiert werden kann . Sie können mithilfe eines regulären Ausdrucks überprüfen, ob eine Postleitzahl im richtigen Format vorliegt. nicht, dass es tatsächlich existiert.

Postleitzahlen sind beliebig komplex und ändern sich ständig. Zum Beispiel hat die Outcode W1nicht und möglicherweise nie jede Nummer zwischen 1 und 99 für jeden Postleitzahlenbereich.

Sie können nicht erwarten, dass das, was derzeit da ist, für immer wahr ist. Zum Beispiel entschied die Post 1990, dass Aberdeen etwas überfüllt war. Sie fügten am Ende von AB1-5 eine 0 hinzu, was AB10-50 ergibt, und erstellten dann eine Reihe von Postleitzahlen dazwischen.

Immer wenn eine neue Straße gebaut wird, wird eine neue Postleitzahl erstellt. Dies ist Teil des Prozesses zur Erlangung der Baugenehmigung. Die lokalen Behörden sind verpflichtet, dies mit der Post auf dem Laufenden zu halten (nicht dass dies alle tun).

Darüber hinaus gibt es, wie von einer Reihe anderer Benutzer festgestellt, spezielle Postleitzahlen wie Girobank, GIR 0AA und die für Briefe an den Weihnachtsmann, SAN TA1 - Sie möchten dort wahrscheinlich nichts posten, aber es scheint nicht so durch eine andere Antwort abgedeckt werden.

Dann gibt es die BFPO-Postleitzahlen, die jetzt auf ein Standardformat umgestellt werden . Beide Formate sind gültig. Schließlich gibt es die Quelle Wikipedia für Überseegebiete .

+ ---------- + -------------------------------------- -------- +
| Postleitzahl | Standort |
+ ---------- + -------------------------------------- -------- +
| AI-2640 | Anguilla |
| ASCN 1ZZ | Ascension Island |
| STHL 1ZZ | St. Helena |
| TDCU 1ZZ | Tristan da Cunha |
| BBND 1ZZ | Britisches Territorium im Indischen Ozean |
| BIQQ 1ZZ | Britisches Antarktisgebiet |
| FIQQ 1ZZ | Falklandinseln |
| GX11 1AA | Gibraltar |
| PCRN 1ZZ | Pitcairninseln |
| SIQQ 1ZZ | Südgeorgien und die Südlichen Sandwichinseln |
| TKCA 1ZZ | Turks- und Caicosinseln |
+ ---------- + -------------------------------------- -------- +

Als nächstes müssen Sie berücksichtigen, dass Großbritannien sein Postleitzahlensystem an viele Orte der Welt "exportiert" hat. Alles, was eine "UK" -Postleitzahl validiert, validiert auch die Postleitzahlen einer Reihe anderer Länder.

Wenn Sie eine britische Postleitzahl validieren möchten, ist es am sichersten, die aktuellen Postleitzahlen nachzuschlagen. Es gibt eine Reihe von Optionen:

  • Ordnance Survey veröffentlicht Code-Point Open unter einer Open-Data-Lizenz. Es wird etwas hinter der Zeit liegen, aber es ist kostenlos. Dies wird (wahrscheinlich - ich kann mich nicht erinnern) keine nordirischen Daten enthalten, da die Ordnance Survey dort keinen Aufgabenbereich hat. Die Kartierung in Nordirland wird von der Ordnance Survey of Northern Ireland durchgeführt und sie haben ihr separates, kostenpflichtiges Zeigerprodukt . Sie können dies verwenden und die wenigen anhängen, die nicht so einfach behandelt werden.

  • Royal Mail veröffentlicht die Postleitzahl-Adressdatei (PAF) , einschließlich BFPO, von der ich nicht sicher bin, ob Code-Point Open dies tut. Es wird regelmäßig aktualisiert, kostet aber Geld (und sie können manchmal geradezu gemein sein). PAF enthält die vollständige Adresse und nicht nur Postleitzahlen und wird mit einem eigenen Programmierhandbuch geliefert . Die Open Data User Group (ODUG) setzt sich derzeit dafür ein, dass PAF kostenlos veröffentlicht wird. Hier finden Sie eine Beschreibung ihrer Position .

  • Schließlich gibt es noch AddressBase . Dies ist eine Zusammenarbeit zwischen Ordnance Survey, Local Authorities, Royal Mail und einem passenden Unternehmen, um ein endgültiges Verzeichnis aller Informationen zu allen britischen Adressen zu erstellen (sie waren auch ziemlich erfolgreich). Es ist bezahlt, aber wenn Sie mit einer lokalen Behörde, einer Regierungsabteilung oder einem Regierungsdienst zusammenarbeiten, können sie diese kostenlos nutzen. Es gibt viel mehr Informationen als nur Postleitzahlen.

Ben
quelle
Das Nachschlagen klingt interessant
SuperUberDuper
2
Dies ist zwar nicht die Antwort, nach der die Operation gesucht hat, aber wahrscheinlich die nützlichste. Dies wird mich ermutigen, die Überprüfungsregeln, die ich tun werde, zu lockern.
John Hunt
22

Ich habe mir einige der obigen Antworten angesehen und würde empfehlen, das Muster aus @ Dans Antwort (ca. 15. Dezember 10) nicht zu verwenden , da es fast 0,4% der gültigen Postleitzahlen fälschlicherweise als ungültig kennzeichnet, während die anderen dies nicht tun .

Ordnance Survey bietet einen Service namens Code Point Open an, der:

enthält eine Liste aller aktuellen Postleitzahleneinheiten in Großbritannien

Ich habe jeden der obigen regulären Ausdrücke anhand dieser Daten gegen die vollständige Liste der Postleitzahlen (6. Juli 13) ausgeführt grep:

cat CSV/*.csv |
    # Strip leading quotes
    sed -e 's/^"//g' |
    # Strip trailing quote and everything after it
    sed -e 's/".*//g' |
    # Strip any spaces
    sed -E -e 's/ +//g' |
    # Find any lines that do not match the expression
    grep --invert-match --perl-regexp "$pattern"

Insgesamt gibt es 1.686.202 Postleitzahlen.

Die folgenden gültigen Postleitzahlen stimmen nicht überein $pattern:

'^([A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]?[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA)$'
# => 6016 (0.36%)
'^(GIR ?0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]([0-9ABEHMNPRV-Y])?)|[0-9][A-HJKPS-UW]) ?[0-9][ABD-HJLNP-UW-Z]{2})$'
# => 0
'^GIR[ ]?0AA|((AB|AL|B|BA|BB|BD|BH|BL|BN|BR|BS|BT|BX|CA|CB|CF|CH|CM|CO|CR|CT|CV|CW|DA|DD|DE|DG|DH|DL|DN|DT|DY|E|EC|EH|EN|EX|FK|FY|G|GL|GY|GU|HA|HD|HG|HP|HR|HS|HU|HX|IG|IM|IP|IV|JE|KA|KT|KW|KY|L|LA|LD|LE|LL|LN|LS|LU|M|ME|MK|ML|N|NE|NG|NN|NP|NR|NW|OL|OX|PA|PE|PH|PL|PO|PR|RG|RH|RM|S|SA|SE|SG|SK|SL|SM|SN|SO|SP|SR|SS|ST|SW|SY|TA|TD|TF|TN|TQ|TR|TS|TW|UB|W|WA|WC|WD|WF|WN|WR|WS|WV|YO|ZE)(\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}))|BFPO[ ]?\d{1,4}$'
# => 0

Diese Ergebnisse beziehen sich natürlich nur auf gültige Postleitzahlen, die fälschlicherweise als ungültig gekennzeichnet sind. So:

'^.*$'
# => 0

Ich sage nichts darüber, welches Muster das beste ist, um ungültige Postleitzahlen herauszufiltern.

RichardTowers
quelle
1
Ist es nicht das, was ich in meiner Antwort sage, und wenn Sie den Weg der Widerlegung beschreiten, sollten Sie wahrscheinlich alle tun und es auf dem neuesten Stand halten, wenn jemand seine Antwort ändert? Wenn nicht, geben Sie zumindest das Datum der letzten Bearbeitung der Antwort an, von der Sie sie übernommen haben, damit die Benutzer sehen können, ob sie seitdem geändert wurde.
Ben
Gutes Argument. Entsprechend bearbeitet. Ich denke, es trägt zur Diskussion bei, darauf hinzuweisen, dass die meisten dieser Muster keinen der CPO-Codes ausschließen, aber dass die am besten bewertete (gültige Regex-) Antwort dies tut. Zukünftige Leser: Seien Sie sich bewusst, dass meine Ergebnisse wahrscheinlich veraltet sind.
RichardTowers
17
^([A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA)$

Regulärer Ausdruck passend zu gültigen britischen Postleitzahlen. Im britischen Postsystem werden nicht alle Buchstaben an allen Positionen verwendet (das gleiche gilt für Kfz-Kennzeichen), und es gibt verschiedene Regeln, die dies regeln. Diese Regex berücksichtigt diese Regeln. Details der Regeln: Erste Hälfte der Postleitzahl Gültige Formate [AZ] [AZ] [0-9] [AZ] [AZ] [AZ] [0-9] [0-9] [AZ] [0-9] [ 0-9] [AZ] [AZ] [0-9] [AZ] [AZ] [AZ] [AZ] [0-9] [AZ] [AZ] [0-9] Ausnahmeposition - Zuerst. Contraint - QVX nicht verwendet Position - Second. Contraint - IJZ wird nur in GIR 0AA Position - Third verwendet. Einschränkung - AEHMNPRTVXY verwendet nur Position - Forth. Contraint - ABEHMNPRVWXY Zweite Hälfte der Postleitzahl Gültige Formate [0-9] [AZ] [AZ] Ausnahmen Position - Zweite und Dritte. Contraint - CIKMOV wird nicht verwendet

http://regexlib.com/REDetails.aspx?regexp_id=260

Dan
quelle
1
Keine Ahnung, warum die Leute diese Antwort abgelehnt haben - es ist die richtige Regex
Ollie
Die Regex funktioniert nicht für die Postleitzahlen "YO31" und "YO31 1" in Javscript.
Pratik Khadloya
9
Ich denke nicht, dass dies richtig ist, da der angegebene 0-9
reguläre Ausdruck
4
Diese Regex schlägt bei ungefähr 6000 gültigen Postleitzahlen fehl, daher würde ich dagegen empfehlen. Siehe meine Antwort .
RichardTowers
Dies schlägt bei jeder Postleitzahl in Kleinbuchstaben oder ohne Leerzeichen für mich fehl
Tänzer
14

Nach dieser Wikipedia-Tabelle

Geben Sie hier die Bildbeschreibung ein

Dieses Muster deckt alle Fälle ab

(?:[A-Za-z]\d ?\d[A-Za-z]{2})|(?:[A-Za-z][A-Za-z\d]\d ?\d[A-Za-z]{2})|(?:[A-Za-z]{2}\d{2} ?\d[A-Za-z]{2})|(?:[A-Za-z]\d[A-Za-z] ?\d[A-Za-z]{2})|(?:[A-Za-z]{2}\d[A-Za-z] ?\d[A-Za-z]{2})

Wenn Sie es unter Android \ Java verwenden, verwenden Sie \\ d

AntPachon
quelle
Ich fand dies die am besten lesbare Antwort, obwohl sie nur nach einer Postleitzahl sucht und nicht nach tatsächlich gültigen Codes gemäß den Lösungen, die die Informationen von der gov.uk-Website übernehmen, aber das ist gut genug für meinen Anwendungsfall. Nachdem ich ein bisschen damit gespielt hatte (in Python), habe ich es zu einem etwas kompakteren, aber äquivalenten regulären Ausdruck herausgerechnet, der auch ein optionales Leerzeichen zulässt: ([a-zA-Z] (?: (?: [A-zA- Z]? \ D [a-zA-Z]) | (?: \ D {1,2}) | (?: [A-zA-Z] \ d {1,2})) \ W? [0 -9] [a-zA-Z] {2})
Richard J.
14

Die meisten Antworten hier funktionierten nicht für alle Postleitzahlen, die ich in meiner Datenbank habe. Ich habe endlich eine gefunden, die mit allen validiert, unter Verwendung des neuen regulären Ausdrucks, der von der Regierung bereitgestellt wurde:

https://www.gov.uk/government/uploads/system/uploads/attachment_data/file/413338/Bulk_Data_Transfer_-_additional_validation_valid_from_March_2015.pdf

Es ist in keiner der vorherigen Antworten enthalten, daher poste ich es hier, falls der Link entfernt wird:

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$

UPDATE: Regex aktualisiert, wie von Jamie Bull gezeigt. Ich bin mir nicht sicher, ob es mein Fehler beim Kopieren oder ein Fehler in der Regex der Regierung war. Der Link ist jetzt nicht mehr verfügbar.

UPDATE: Wie ctwheels festgestellt hat, funktioniert dieser Regex mit dem Javascript-Regex-Geschmack. Siehe seinen Kommentar für einen, der mit dem pcre (php) Geschmack arbeitet.

Jesús Carrera
quelle
1
^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$sollte sein ^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$- den Unterschied erkennen ;-)
Jamie Bull
1
Genau richtig! Meine Antwort wurde aktualisiert. Vielen Dank!
Jesús Carrera
2
Dies ist die einzige Antwort hier, die in regexr.com und Notepad ++ funktioniert hat . Obwohl ich ändern musste es ([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) ?[0-9][A-Za-z]{2})(entfernt ^und $und eine hinzugefügt ?nach dem Raum) für regexr.com mehr als ein Ergebnis zu finden und für beide ein Ergebnis zu finden , die keinen Raum seperator haben.
Mythosofechelon
@ctwheels Dieser Regex ist für das Javascript-Aroma. Wenn Sie in Fail-Link Javascript auswählen, funktioniert es. Das ist ein großartiger Fang und ich werde meine Antwort aktualisieren.
Jesús Carrera
1
Der in der Dokumentation angegebene reguläre Ausdruck ist von Natur aus falsch. Der gesamte Ausdruck sollte in eine nicht erfassende Gruppe eingeschlossen (?:)und dann um sie herum verankert werden. Sehen Sie, wie es hier fehlschlägt . Weitere Informationen finden Sie in meiner Antwort hier . ^(?:([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2}))$ist der korrigierte reguläre Ausdruck.
ctwheels
12

Ein alter Beitrag, aber immer noch ziemlich hoch in den Google-Ergebnissen, also dachte ich, ich würde aktualisieren. In diesem Dokument vom 14. Oktober wird der reguläre Ausdruck der britischen Postleitzahl wie folgt definiert:

^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([**AZ**a-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$

von:

https://www.gov.uk/government/uploads/system/uploads/attachment_data/file/359448/4__Bulk_Data_Transfer_-_additional_validation_valid.pdf

Das Dokument erklärt auch die Logik dahinter. Es hat jedoch einen Fehler (fett gedruckt) und erlaubt auch Kleinbuchstaben, was, obwohl legal nicht üblich ist, so geänderte Version:

^(GIR 0AA)|((([A-Z][0-9]{1,2})|(([A-Z][A-HJ-Y][0-9]{1,2})|(([A-Z][0-9][A-Z])|([A-Z][A-HJ-Y][0-9]?[A-Z])))) [0-9][A-Z]{2})$

Dies funktioniert mit neuen Londoner Postleitzahlen (z. B. W1D 5LH), die in früheren Versionen nicht verfügbar waren.

tote Krabbe
quelle
Es sieht so aus, als ob der fett markierte Fehler im Dokument behoben wurde, aber ich bevorzuge immer noch Ihren regulären Ausdruck, da er leichter zu lesen ist.
Professor für Programmierung
5
Das einzige, was ich sagen würde, ist, den Speicherplatz optional zu machen, indem Sie den Speicherplatz in \ s ändern. Da der Platz keine Voraussetzung für die Lesbarkeit ist.
Professor für Programmierung
Der in der Dokumentation angegebene reguläre Ausdruck ist von Natur aus falsch. Der gesamte Ausdruck sollte in eine nicht erfassende Gruppe eingeschlossen (?:)und dann um sie herum verankert werden. Sehen Sie, wie es hier fehlschlägt . Weitere Informationen finden Sie in meiner Antwort hier . ^(?:([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2}))$ist der korrigierte reguläre Ausdruck.
ctwheels
10

Dies ist der reguläre Ausdruck, den Google auf seiner Domain i18napis.appspot.com bereitstellt :

GIR[ ]?0AA|((AB|AL|B|BA|BB|BD|BH|BL|BN|BR|BS|BT|BX|CA|CB|CF|CH|CM|CO|CR|CT|CV|CW|DA|DD|DE|DG|DH|DL|DN|DT|DY|E|EC|EH|EN|EX|FK|FY|G|GL|GY|GU|HA|HD|HG|HP|HR|HS|HU|HX|IG|IM|IP|IV|JE|KA|KT|KW|KY|L|LA|LD|LE|LL|LN|LS|LU|M|ME|MK|ML|N|NE|NG|NN|NP|NR|NW|OL|OX|PA|PE|PH|PL|PO|PR|RG|RH|RM|S|SA|SE|SG|SK|SL|SM|SN|SO|SP|SR|SS|ST|SW|SY|TA|TD|TF|TN|TQ|TR|TS|TW|UB|W|WA|WC|WD|WF|WN|WR|WS|WV|YO|ZE)(\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}))|BFPO[ ]?\d{1,4}
Alix Axel
quelle
10

Postleitzahlen können sich ändern. Die einzig wahre Möglichkeit, eine Postleitzahl zu validieren, besteht darin, die vollständige Liste der Postleitzahlen zu haben und zu prüfen, ob sie vorhanden ist.

Aber reguläre Ausdrücke sind nützlich, weil sie:

  • sind einfach zu bedienen und zu implementieren
  • sind kurz
  • sind schnell zu rennen
  • sind recht einfach zu pflegen (im Vergleich zu einer vollständigen Liste von Postleitzahlen)
  • fangen immer noch die meisten Eingabefehler

Aber reguläre Ausdrücke sind in der Regel schwer zu pflegen, insbesondere für jemanden, der sie überhaupt nicht erfunden hat. So muss es sein:

  • so einfach wie möglich zu verstehen
  • relativ zukunftssicher

Das bedeutet, dass die meisten regulären Ausdrücke in dieser Antwort nicht gut genug sind. ZB kann ich das sehen[A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRV-Y] mit einem Postleitzahlenbereich der Form AA1A übereinstimmt - aber es wird schmerzhaft sein, wenn ein neuer Postleitzahlenbereich hinzugefügt wird, da es schwierig ist zu verstehen, mit welchen Postleitzahlenbereichen er übereinstimmt.

Ich möchte auch, dass mein regulärer Ausdruck mit der ersten und zweiten Hälfte der Postleitzahl in Klammern übereinstimmt.

Also habe ich mir Folgendes ausgedacht:

(GIR(?=\s*0AA)|(?:[BEGLMNSW]|[A-Z]{2})[0-9](?:[0-9]|(?<=N1|E1|SE1|SW1|W1|NW1|EC[0-9]|WC[0-9])[A-HJ-NP-Z])?)\s*([0-9][ABD-HJLNP-UW-Z]{2})

Im PCRE-Format kann es wie folgt geschrieben werden:

/^
  ( GIR(?=\s*0AA) # Match the special postcode "GIR 0AA"
    |
    (?:
      [BEGLMNSW] | # There are 8 single-letter postcode areas
      [A-Z]{2}     # All other postcode areas have two letters
      )
    [0-9] # There is always at least one number after the postcode area
    (?:
      [0-9] # And an optional extra number
      |
      # Only certain postcode areas can have an extra letter after the number
      (?<=N1|E1|SE1|SW1|W1|NW1|EC[0-9]|WC[0-9])
      [A-HJ-NP-Z] # Possible letters here may change, but [IO] will never be used
      )?
    )
  \s*
  ([0-9][ABD-HJLNP-UW-Z]{2}) # The last two letters cannot be [CIKMOV]
$/x

Für mich ist dies die richtige Balance zwischen einer möglichst umfassenden Validierung bei gleichzeitiger Zukunftssicherheit und einer einfachen Wartung.

andre
quelle
Ich bin mir nicht sicher, warum Sie abgewählt wurden - dies funktioniert mit allen gültigen Postleitzahlen, die ich darauf geworfen habe, und Leerzeichen, die in vielen der obigen Antworten nicht richtig behandelt werden. Würde jemand gerne erklären, warum?
Jon
1
@ Jon Es stimmt auch überein, wenn andere Zeichen an den Anfang oder das Ende angehängt werden, z. B. aSW1A 1AAasfgpassend für mich (ich habe jedoch nicht herabgestimmt, da es so aussieht, als könnte es leicht behoben werden)
devaliert den
9

Ich habe für den letzten Tag nach einer britischen Postleitzahl gesucht und bin über diesen Thread gestolpert. Ich habe mich durch die meisten der oben genannten Vorschläge gearbeitet, und keiner von ihnen hat für mich funktioniert. Deshalb habe ich mir einen eigenen regulären Ausdruck ausgedacht, der, soweit ich weiß, alle gültigen britischen Postleitzahlen ab dem 13. Januar erfasst (gemäß der neuesten Literatur von die Royal Mail).

Der reguläre Ausdruck und einige einfache PHP-Codes zur Überprüfung der Postleitzahl sind unten aufgeführt. HINWEIS: - Es ermöglicht Postleitzahlen in Klein- oder Großbuchstaben und die GIR 0AA-Anomalie. Um jedoch das Vorhandensein eines Leerzeichens in der Mitte einer eingegebenen Postleitzahl zu behandeln, wird vor dem Testen auch ein einfaches str_replace verwendet, um das Leerzeichen zu entfernen gegen die Regex. Darüber hinausgehende Unstimmigkeiten und die Royal Mail selbst erwähnen sie nicht einmal in ihrer Literatur (siehe http://www.royalmail.com/sites/default/files/docs/pdf/programmers_guide_edition_7_v5.pdf und lesen Sie ab Seite 17). !

Hinweis: In der eigenen Literatur der Royal Mail (Link oben) gibt es eine leichte Unklarheit in Bezug auf die 3. und 4. Position und die Ausnahmen, wenn diese Zeichen Buchstaben sind. Ich habe Royal Mail direkt kontaktiert, um es zu klären, und zwar mit eigenen Worten: "Ein Brief an der 4. Position des Outward Code mit dem Format AANA NAA hat keine Ausnahmen, und die Ausnahmen an der 3. Position gelten nur für den letzten Buchstaben des Outward Code mit dem Format ANA NAA. " Direkt aus dem Maul des Pferdes!

<?php

    $postcoderegex = '/^([g][i][r][0][a][a])$|^((([a-pr-uwyz]{1}([0]|[1-9]\d?))|([a-pr-uwyz]{1}[a-hk-y]{1}([0]|[1-9]\d?))|([a-pr-uwyz]{1}[1-9][a-hjkps-uw]{1})|([a-pr-uwyz]{1}[a-hk-y]{1}[1-9][a-z]{1}))(\d[abd-hjlnp-uw-z]{2})?)$/i';

    $postcode2check = str_replace(' ','',$postcode2check);

    if (preg_match($postcoderegex, $postcode2check)) {

        echo "$postcode2check is a valid postcode<br>";

    } else {

        echo "$postcode2check is not a valid postcode<br>";

    }

?>

Ich hoffe, es hilft allen anderen, die auf diesen Thread stoßen, nach einer Lösung zu suchen.

Dan Solo
quelle
1
Ich wäre gespannt, welche Beispiel-Postleitzahlen die veröffentlichte nicht bestanden haben.
Zhaph - Ben Duguid
Ich kann Ihnen keine bestimmte Postleitzahl geben (ohne Zugriff auf die vollständige PAF-Liste), aber Postleitzahlen mit dem Format ANA NAA würden möglicherweise fehlschlagen, da die Buchstaben P und Q an dritter Stelle zulässig sind und Postleitzahlen mit dem Format AANA NAA möglicherweise scheitern auch, da die 4. Position alle Buchstaben zulässt (der in der oben akzeptierten Antwort angegebene reguläre Ausdruck berücksichtigt keinen dieser Buchstaben). Wie ich bereits sagte, befolge ich nur die aktuellen Ratschläge der Royal Mail - zum Zeitpunkt der obigen Antwort war diese Regex möglicherweise vollständig konform.
Dan Solo
Vielen Dank für das Heads-up - ich kann sehen, dass "P" an der dritten Position (aus Ihrem verlinkten Dokument) als akzeptabel hinzugefügt wurde, aber nicht an Q - aber wo lesen Sie, dass "die vierte Position alle Buchstaben erlaubt"? Der Arzt erwähnt die "vierte Position" überhaupt nicht, soweit ich sehen kann, also würde ich das als "den dritten Buchstaben unabhängig von der tatsächlichen Position" lesen.
Zhaph - Ben Duguid
1
Ich habe gerade eine Nachricht vom Royal Mail-Support-Team erhalten und meine Interpretation der Regeln ist anscheinend korrekt. Ein Buchstabe an der 4. Position des Outward Code (z. B. AANA NAA) hat keine Ausnahmen, und die Ausnahmen an der 3. Position gelten nur für den letzten Buchstaben (z. B. ANA NAA). Direkt aus dem Maul des Pferdes.
Dan Solo
1
@ DanSolo Dieser reguläre Ausdruck gibt eine echte Übereinstimmung für die erste Hälfte einer gültigen Postleitzahl zurück, bei der der interne Code fehlt, z. B. SW1Aoder BD25ohne die zweite Hälfte (oder zumindest für mich)
devaliert den
7

Hier ist eine Regex, die auf dem Format basiert, das in den Dokumenten angegeben ist, die mit der Antwort von marcj verknüpft sind:

/^[A-Z]{1,2}[0-9][0-9A-Z]? ?[0-9][A-Z]{2}$/

Der einzige Unterschied zwischen diesem und den Spezifikationen besteht darin, dass die letzten 2 Zeichen gemäß den Spezifikationen nicht in [CIKMOV] enthalten sein können.

Bearbeiten: Hier ist eine andere Version, die die Einschränkungen für nachfolgende Zeichen testet.

/^[A-Z]{1,2}[0-9][0-9A-Z]? ?[0-9][A-BD-HJLNP-UW-Z]{2}$/
Will Tomlins
quelle
Eine britische Postleitzahl ist viel komplexer als nur das Akzeptieren A-Z- dies Qist niemals erlaubt, Vwird nur sparsam verwendet usw., abhängig von der Position des Charakters.
Zhaph - Ben Duguid
2
Das ist vielleicht irrelevant, wenn Sie eine Syntaxprüfung wünschen. Wie viele andere bemerkt haben, wird nur eine Suche in einer aktuellen Datenbank nahezu korrekt, und selbst dann besteht das Problem, wie aktuell die Datenbank ist. Für mich ist dieser reguläre Ausdruck der Syntaxprüfung klar, einfach und nützlich.
Rick-777
5

Einige der oben genannten regulären Ausdrücke sind etwas restriktiv. Beachten Sie die echte Postleitzahl: "W1K 7AA" würde fehlschlagen, wenn die oben verwendete Regel "Position 3 - AEHMNPRTVXY nur verwendet" als "K" nicht zulässig wäre.

die Regex:

^(GIR 0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]|[A-HK-Y][0-9]([0-9]|[ABEHMNPRV-Y]))|[0-9][A-HJKPS-UW])[0-9][ABD-HJLNP-UW-Z]{2})$

Scheint etwas genauer zu sein, siehe den Wikipedia-Artikel mit dem Titel "Postleitzahlen im Vereinigten Königreich" .

Beachten Sie, dass für diesen regulären Ausdruck nur Großbuchstaben erforderlich sind.

Die größere Frage ist, ob Sie die Benutzereingabe einschränken, um nur tatsächlich vorhandene Postleitzahlen zuzulassen, oder ob Sie einfach versuchen, Benutzer daran zu hindern, vollständigen Müll in die Formularfelder einzugeben. Es ist schwieriger, jede mögliche Postleitzahl richtig abzugleichen und sie zukunftssicher zu machen, und es lohnt sich wahrscheinlich nicht, es sei denn, Sie sind HMRC.

Minglis
quelle
Sieht aus wie die Post weitergezogen ist, aber die Regierung ist etwas zurückgeblieben :(
Zhaph - Ben Duguid
4
Ich benutze dieses: "^ ([Gg] [Ii] [Rr] 0 [Aa] {2}) | ((([A-Za-z] [0-9] {1,2}) | (( [A-Za-z] [A-Ha-hJ-Yj-y] [0-9] {1,2}) | (([A-Za-z] [0-9] [A-Za-z ]) | ([A-Za-z] [A-Ha-hJ-Yj-y] [0-9]? [A-Za-z])))) {0,1} [0-9] [ A-Za-z] {2}) $ "Ich mag es, weil es Groß- und Kleinbuchstaben zulässt und den Platz optional macht - besser für die Benutzerfreundlichkeit, wenn nicht 100% korrekt!
Bigtv
4

So haben wir mit dem Problem der britischen Postleitzahl umgegangen:

^([A-Za-z]{1,2}[0-9]{1,2}[A-Za-z]?[ ]?)([0-9]{1}[A-Za-z]{2})$

Erläuterung:

  • Erwarten Sie 1 oder 2 Az Zeichen, obere oder untere Geldstrafe
  • Erwarten Sie 1 oder 2 Zahlen
  • Erwarten Sie 0 oder 1 Az Char, obere oder untere Geldstrafe
  • optionaler Platz erlaubt
  • Erwarten Sie 1 Nummer
  • Erwarten Sie 2 az, obere oder untere Geldstrafe

Dies erhält die meisten Formate. Wir verwenden dann die Datenbank, um zu überprüfen, ob die Postleitzahl tatsächlich echt ist. Diese Daten werden von openpoint https://www.ordnancesurvey.co.uk/opendatadownload/products.html gesteuert

hoffe das hilft

Alex Stephens
quelle
Dies ermöglicht das AANNA NAAungültige Format .
ctwheels
Daher der Teil "Dies erhält die meisten Formate" der Antwort. :)
Alex Stephens
4

Grundregeln:

^[A-Z]{1,2}[0-9R][0-9A-Z]? [0-9][ABD-HJLNP-UW-Z]{2}$

Postleitzahlen in Großbritannien (oder Postleitzahlen, wie sie genannt werden) bestehen aus fünf bis sieben alphanumerischen Zeichen, die durch ein Leerzeichen getrennt sind. Die Regeln, nach denen Zeichen an bestimmten Positionen erscheinen können, sind ziemlich kompliziert und mit Ausnahmen behaftet. Der gerade gezeigte reguläre Ausdruck hält sich daher an die Grundregeln.

Vollständige Regeln:

Wenn Sie einen regulären Ausdruck benötigen, der auf Kosten der Lesbarkeit alle Kästchen für die Postleitzahlenregeln ankreuzt, können Sie Folgendes tun:

^(?:(?:[A-PR-UWYZ][0-9]{1,2}|[A-PR-UWYZ][A-HK-Y][0-9]{1,2}|[A-PR-UWYZ][0-9][A-HJKSTUW]|[A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRV-Y]) [0-9][ABD-HJLNP-UW-Z]{2}|GIR 0AA)$

Quelle: https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9781449327453/ch04s16.html

Getestet gegen unsere Kundendatenbank und scheint vollkommen genau zu sein.

Raphos
quelle
4

Ich verwende den folgenden regulären Ausdruck, den ich gegen alle gültigen britischen Postleitzahlen getestet habe. Es basiert auf den empfohlenen Regeln, ist jedoch so weit wie möglich komprimiert und verwendet keine speziellen sprachspezifischen Regex-Regeln.

([A-PR-UWYZ]([A-HK-Y][0-9]([0-9]|[ABEHMNPRV-Y])?|[0-9]([0-9]|[A-HJKPSTUW])?) ?[0-9][ABD-HJLNP-UW-Z]{2})

Es wird davon ausgegangen, dass die Postleitzahl in Großbuchstaben konvertiert wurde und keine führenden oder nachfolgenden Zeichen enthält, jedoch ein optionales Leerzeichen zwischen der Postleitzahl und der Incode akzeptiert.

Die spezielle Postleitzahl "GIR0 0AA" ist ausgeschlossen und wird nicht validiert, da sie nicht in der offiziellen Postleitzahlliste der Post enthalten ist und meines Wissens nicht als registrierte Adresse verwendet wird. Das Hinzufügen sollte bei Bedarf als Sonderfall trivial sein.

Meißel
quelle
4

Ich wollte einen einfachen regulären Ausdruck, bei dem es in Ordnung ist, zu viel zuzulassen, aber keine gültige Postleitzahl zu verweigern. Ich habe mich dafür entschieden (die Eingabe ist eine abgespeckte Zeichenfolge):

/^([a-z0-9]\s*){5,8}$/i

Dies ermöglicht die kürzestmöglichen Postleitzahlen wie "L1 8JQ" sowie die längsten wie "OL14 5ET".

Da bis zu 8 Zeichen zulässig sind, sind auch falsche Postleitzahlen mit 8 Zeichen zulässig, wenn kein Leerzeichen vorhanden ist: "OL145ETX". Aber auch dies ist eine vereinfachte Regex, wenn das gut genug ist.

Henrik N.
quelle
Oh, ich entschuldige mich. Ich glaube, ich habe das / i verpasst, als ich gestern getestet habe.
John
3

Erste Hälfte der Postleitzahl Gültige Formate

  • [AZ] [AZ] [0-9] [AZ]
  • [AZ] [AZ] [0-9] [0-9]
  • [AZ] [0-9] [0-9]
  • [AZ] [AZ] [0-9]
  • [AZ] [AZ] [AZ]
  • [AZ] [0-9] [AZ]
  • [AZ] [0-9]

Ausnahmen
Position 1 - QVX nicht verwendet
Position 2 - IJZ nicht verwendet, außer in GIR 0AA
Position 3 - AEHMNPRTVXY nur verwendet
Position 4 - ABEHMNPRVWXY

Zweite Hälfte der Postleitzahl

  • [0-9] [AZ] [AZ]

Ausnahmen
Position 2 + 3 - CIKMOV wird nicht verwendet

Denken Sie daran, dass nicht alle möglichen Codes verwendet werden. Daher ist diese Liste eine notwendige, aber nicht ausreichende Bedingung für einen gültigen Code. Es könnte einfacher sein, nur mit einer Liste aller gültigen Codes abzugleichen?

Martin Beckett
quelle
3

So überprüfen Sie, ob eine Postleitzahl in einem gültigen Format gemäß dem Programmierhandbuch von Royal Mail vorliegt :

          |----------------------------outward code------------------------------| |------inward code-----|
#special↓       α1        α2    AAN  AANA      AANN      AN    ANN    ANA (α3)        N         AA
^(GIR 0AA|[A-PR-UWYZ]([A-HK-Y]([0-9][A-Z]?|[1-9][0-9])|[1-9]([0-9]|[A-HJKPSTUW])?) [0-9][ABD-HJLNP-UW-Z]{2})$

Alle Postleitzahlen auf doogal.de überein, mit Ausnahme der nicht mehr verwendeten.

Hinzufügen eines ?Nach-Leerzeichens und Verwenden der Übereinstimmung ohne Berücksichtigung der Groß- und Kleinschreibung, um diese Frage zu beantworten:

'se50eg'.match(/^(GIR 0AA|[A-PR-UWYZ]([A-HK-Y]([0-9][A-Z]?|[1-9][0-9])|[1-9]([0-9]|[A-HJKPSTUW])?) ?[0-9][ABD-HJLNP-UW-Z]{2})$/ig);
Array [ "se50eg" ]
Jackson Pauls
quelle
3

Dieser erlaubt Leerzeichen und Tabulatoren von beiden Seiten, falls Sie die Validierung nicht fehlschlagen möchten, und schneidet sie dann ab.

^\s*(([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) {0,1}[0-9][A-Za-z]{2})\s*$)
Matas Vaitkevicius
quelle
Dies ist das einzige Muster, das für mich mit c # (System.Text.RegularExpressions) mit den in der ursprünglichen Frage beschriebenen Beispielen
funktioniert hat
Dies ist der gebrochene reguläre Ausdruck der britischen Regierung, und einige der gültigen Formate können nicht validiert werden.
ctwheels
@ctwheels Hallo, könnten Sie bitte eine fehlerhafte Postleitzahl angeben, danke.
Matas Vaitkevicius
ZB AAA 1AAist kein gültiges Format: Eine Erklärung und Korrektur finden Sie in meiner Antwort .
ctwheels
2

Um dieser Liste einen praktischeren regulären Ausdruck hinzuzufügen, den ich verwende, mit dem der Benutzer einen eingeben kann, empty stringlautet:

^$|^(([gG][iI][rR] {0,}0[aA]{2})|((([a-pr-uwyzA-PR-UWYZ][a-hk-yA-HK-Y]?[0-9][0-9]?)|(([a-pr-uwyzA-PR-UWYZ][0-9][a-hjkstuwA-HJKSTUW])|([a-pr-uwyzA-PR-UWYZ][a-hk-yA-HK-Y][0-9][abehmnprv-yABEHMNPRV-Y]))) {0,1}[0-9][abd-hjlnp-uw-zABD-HJLNP-UW-Z]{2}))$

Diese Regex ermöglicht Groß- und Kleinbuchstaben mit einem optionalen Leerzeichen dazwischen

Aus Sicht der Softwareentwickler ist dieser reguläre Ausdruck nützlich für Software, bei der eine Adresse optional sein kann. Zum Beispiel, wenn ein Benutzer seine Adressdaten nicht angeben wollte

user1
quelle
1

Schauen Sie sich den Python-Code auf dieser Seite an:

http://www.brunningonline.net/simon/blog/archives/001292.html

Ich muss einige Postleitzahlen analysieren. Die Anforderung ist ziemlich einfach; Ich muss eine Postleitzahl in eine Outcode und eine (optionale) Incode analysieren. Das Gute daran ist, dass ich keine Validierung durchführen muss - ich muss nur das, was mir zur Verfügung gestellt wurde, auf vage intelligente Weise zerhacken. Ich kann nicht viel über meinen Import in Bezug auf Formatierung, dh Groß- und Kleinschreibung und eingebettete Leerzeichen, annehmen. Aber das sind keine schlechten Nachrichten. Die schlechte Nachricht ist, dass ich alles im Rollenspiel machen muss. :-(

Trotzdem habe ich eine kleine Python-Funktion zusammengeschmissen, um mein Denken zu verdeutlichen.

Ich habe es verwendet, um Postleitzahlen für mich zu verarbeiten.

Rüdiger Wolf
quelle
1

Wir erhielten eine Spezifikation:

Postleitzahlen in Großbritannien müssen in einer der folgenden Formen vorliegen (mit einer Ausnahme, siehe unten): 
    § A9 9AA 
    § A99 9AA
    § AA9 9AA
    § AA99 9AA
    § A9A 9AA
    § AA9A 9AA
Dabei steht A für ein alphabetisches Zeichen und 9 für ein numerisches Zeichen.
Für alphabetische Zeichen gelten folgende zusätzliche Regeln:
    § Das Zeichen in Position 1 darf nicht Q, V oder X sein
    § Das Zeichen in Position 2 darf nicht I, J oder Z sein
    § Das Zeichen in Position 3 darf nicht I, L, M, N, O, P, Q, R, V, X, Y oder Z sein
    § Das Zeichen in Position 4 darf nicht C, D, F, G, I, J, K, L, O, Q, S, T, U oder Z sein
    § Die Zeichen an den beiden Positionen ganz rechts dürfen nicht C, I, K, M, O oder V sein
Die einzige Ausnahme, die diesen allgemeinen Regeln nicht entspricht, ist die Postleitzahl "GIR 0AA", eine spezielle gültige Postleitzahl.

Wir haben uns Folgendes ausgedacht:

/^([A-PR-UWYZ][A-HK-Y0-9](?:[A-HJKS-UW0-9][ABEHMNPRV-Y0-9]?)?\s*[0-9][ABD-HJLNP-UW-Z]{2}|GIR\s*0AA)$/i

Beachten Sie jedoch, dass zwischen den Gruppen beliebig viele Leerzeichen vorhanden sind.

paulslater19
quelle
2
paulslater19, leider erlaubt Ihre Lösung A99A 9AA Postleitzahlen.
1

Ich habe den regulären Ausdruck für die Validierung der britischen Postleitzahl.

Dies funktioniert für alle Arten von Postleitzahlen, entweder innen oder außen

^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))) || ^((GIR)[ ]?(0AA))$|^(([A-PR-UWYZ][0-9])[ ]?([0-9][ABD-HJLNPQ-UW-Z]{0,2}))$|^(([A-PR-UWYZ][0-9][0-9])[ ]?([0-9][ABD-HJLNPQ-UW-Z]{0,2}))$|^(([A-PR-UWYZ][A-HK-Y0-9][0-9])[ ]?([0-9][ABD-HJLNPQ-UW-Z]{0,2}))$|^(([A-PR-UWYZ][A-HK-Y0-9][0-9][0-9])[ ]?([0-9][ABD-HJLNPQ-UW-Z]{0,2}))$|^(([A-PR-UWYZ][0-9][A-HJKS-UW0-9])[ ]?([0-9][ABD-HJLNPQ-UW-Z]{0,2}))$|^(([A-PR-UWYZ][A-HK-Y0-9][0-9][ABEHMNPRVWXY0-9])[ ]?([0-9][ABD-HJLNPQ-UW-Z]{0,2}))$

Dies funktioniert für alle Arten von Formaten.

Beispiel:

AB10 --------------------> NUR AUSSENPOSTCODE

A1 1AA ------------------> KOMBINATION VON (AUSSEN UND INNEN) POSTCODE

WC2A --------------------> AUSSEN

Schneller Meister
quelle
1

Die akzeptierte Antwort entspricht den Regeln von Royal Mail, obwohl der reguläre Ausdruck einen Tippfehler enthält. Dieser Tippfehler scheint auch auf der Website gov.uk vorhanden zu sein (wie auf der XML-Archivseite).

Im Format A9A 9AA erlauben die Regeln ein P-Zeichen an dritter Stelle, während der Regex dies nicht zulässt. Der richtige reguläre Ausdruck wäre:

(GIR 0AA)|((([A-Z-[QVX]][0-9][0-9]?)|(([A-Z-[QVX]][A-Z-[IJZ]][0-9][0-9]?)|(([A-Z-[QVX]][0-9][A-HJKPSTUW])|([A-Z-[QVX]][A-Z-[IJZ]][0-9][ABEHMNPRVWXY])))) [0-9][A-Z-[CIKMOV]]{2}) 

Wenn Sie dies verkürzen, erhalten Sie den folgenden regulären Ausdruck (der die Perl / Ruby-Syntax verwendet):

(GIR 0AA)|([A-PR-UWYZ](([0-9]([0-9A-HJKPSTUW])?)|([A-HK-Y][0-9]([0-9ABEHMNPRVWXY])?))\s?[0-9][ABD-HJLNP-UW-Z]{2})

Es enthält auch einen optionalen Abstand zwischen dem ersten und dem zweiten Block.

Stieb
quelle
1

Was ich in fast allen Variationen und dem regulären Ausdruck aus dem Massenübertragungs-PDF gefunden habe und was auf der Wikipedia-Site steht, ist, dass speziell für den Wikipedia-regulären Ausdruck ein ^ nach dem ersten | (vertikaler Balken) stehen muss. Ich habe dies durch Testen auf AA9A 9AA herausgefunden, da sonst die Formatprüfung für A9A 9AA dies validiert. Zum Beispiel wird die Überprüfung auf EC1D 1BB, die ungültig sein sollte, wieder gültig, da C1D 1BB ein gültiges Format ist.

Folgendes habe ich mir für eine gute Regex ausgedacht:

^([G][I][R] 0[A]{2})|^((([A-Z-[QVX]][0-9]{1,2})|([A-Z-[QVX]][A-HK-Y][0-9]{1,2})|([A-Z-[QVX]][0-9][ABCDEFGHJKPSTUW])|([A-Z-[QVX]][A-HK-Y][0-9][ABEHMNPRVWXY])) [0-9][A-Z-[CIKMOV]]{2})$
Andrew Schliewe
quelle
1

Durch empirische Tests und Beobachtung sowie die Bestätigung mit https://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom#Validation , hier ist meine Version einer Python , die richtig Parsen regex und validiert eine britische Postleitzahl:

UK_POSTCODE_REGEX = r'(?P<postcode_area>[A-Z]{1,2})(?P<district>(?:[0-9]{1,2})|(?:[0-9][A-Z]))(?P<sector>[0-9])(?P<postcode>[A-Z]{2})'

Dieser reguläre Ausdruck ist einfach und verfügt über Erfassungsgruppen. Es enthält nicht alle Validierungen legaler britischer Postleitzahlen, sondern berücksichtigt nur die Positionen von Buchstaben und Zahlen.

Hier ist, wie ich es im Code verwenden würde:

@dataclass
class UKPostcode:
    postcode_area: str
    district: str
    sector: int
    postcode: str

    # https://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom#Validation
    # Original author of this regex: @jontsai
    # NOTE TO FUTURE DEVELOPER:
    # Verified through empirical testing and observation, as well as confirming with the Wiki article
    # If this regex fails to capture all valid UK postcodes, then I apologize, for I am only human.
    UK_POSTCODE_REGEX = r'(?P<postcode_area>[A-Z]{1,2})(?P<district>(?:[0-9]{1,2})|(?:[0-9][A-Z]))(?P<sector>[0-9])(?P<postcode>[A-Z]{2})'

    @classmethod
    def from_postcode(cls, postcode):
        """Parses a string into a UKPostcode

        Returns a UKPostcode or None
        """
        m = re.match(cls.UK_POSTCODE_REGEX, postcode.replace(' ', ''))

        if m:
            uk_postcode = UKPostcode(
                postcode_area=m.group('postcode_area'),
                district=m.group('district'),
                sector=m.group('sector'),
                postcode=m.group('postcode')
            )
        else:
            uk_postcode = None

        return uk_postcode


def parse_uk_postcode(postcode):
    """Wrapper for UKPostcode.from_postcode
    """
    uk_postcode = UKPostcode.from_postcode(postcode)
    return uk_postcode

Hier sind Unit-Tests:

@pytest.mark.parametrize(
    'postcode, expected', [
        # https://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom#Validation
        (
            'EC1A1BB',
            UKPostcode(
                postcode_area='EC',
                district='1A',
                sector='1',
                postcode='BB'
            ),
        ),
        (
            'W1A0AX',
            UKPostcode(
                postcode_area='W',
                district='1A',
                sector='0',
                postcode='AX'
            ),
        ),
        (
            'M11AE',
            UKPostcode(
                postcode_area='M',
                district='1',
                sector='1',
                postcode='AE'
            ),
        ),
        (
            'B338TH',
            UKPostcode(
                postcode_area='B',
                district='33',
                sector='8',
                postcode='TH'
            )
        ),
        (
            'CR26XH',
            UKPostcode(
                postcode_area='CR',
                district='2',
                sector='6',
                postcode='XH'
            )
        ),
        (
            'DN551PT',
            UKPostcode(
                postcode_area='DN',
                district='55',
                sector='1',
                postcode='PT'
            )
        )
    ]
)
def test_parse_uk_postcode(postcode, expected):
    uk_postcode = parse_uk_postcode(postcode)
    assert(uk_postcode == expected)
Jontsai
quelle
0

Ich brauchte eine Version, die in SAS mit den PRXMATCHund verwandten Funktionen funktioniert, also habe ich mir Folgendes ausgedacht:

^[A-PR-UWYZ](([A-HK-Y]?\d\d?)|(\d[A-HJKPSTUW])|([A-HK-Y]\d[ABEHMNPRV-Y]))\s?\d[ABD-HJLNP-UW-Z]{2}$

Testfälle und Hinweise:

/* 
Notes
The letters QVX are not used in the 1st position.
The letters IJZ are not used in the second position.
The only letters to appear in the third position are ABCDEFGHJKPSTUW when the structure starts with A9A.
The only letters to appear in the fourth position are ABEHMNPRVWXY when the structure starts with AA9A.
The final two letters do not use the letters CIKMOV, so as not to resemble digits or each other when hand-written.
*/

/*
    Bits and pieces
    1st position (any):         [A-PR-UWYZ]         
    2nd position (if letter):   [A-HK-Y]
    3rd position (A1A format):  [A-HJKPSTUW]
    4th position (AA1A format): [ABEHMNPRV-Y]
    Last 2 positions:           [ABD-HJLNP-UW-Z]    
*/


data example;
infile cards truncover;
input valid 1. postcode &$10. Notes &$100.;
flag = prxmatch('/^[A-PR-UWYZ](([A-HK-Y]?\d\d?)|(\d[A-HJKPSTUW])|([A-HK-Y]\d[ABEHMNPRV-Y]))\s?\d[ABD-HJLNP-UW-Z]{2}$/',strip(postcode));
cards;
1  EC1A 1BB  Special case 1
1  W1A 0AX   Special case 2
1  M1 1AE    Standard format
1  B33 8TH   Standard format
1  CR2 6XH   Standard format
1  DN55 1PT  Standard format
0  QN55 1PT  Bad letter in 1st position
0  DI55 1PT  Bad letter in 2nd position
0  W1Z 0AX   Bad letter in 3rd position
0  EC1Z 1BB  Bad letter in 4th position
0  DN55 1CT  Bad letter in 2nd group
0  A11A 1AA  Invalid digits in 1st group
0  AA11A 1AA  1st group too long
0  AA11 1AAA  2nd group too long
0  AA11 1AAA  2nd group too long
0  AAA 1AA   No digit in 1st group
0  AA 1AA    No digit in 1st group
0  A 1AA     No digit in 1st group
0  1A 1AA    Missing letter in 1st group
0  1 1AA     Missing letter in 1st group
0  11 1AA    Missing letter in 1st group
0  AA1 1A    Missing letter in 2nd group
0  AA1 1     Missing letter in 2nd group
;
run;
user667489
quelle
0

Die folgende Methode überprüft die Postleitzahl und liefert vollständige Informationen

const valid_postcode = postcode => {
    try {
        postcode = postcode.replace(/\s/g, "");
        const fromat = postcode
            .toUpperCase()
            .match(/^([A-Z]{1,2}\d{1,2}[A-Z]?)\s*(\d[A-Z]{2})$/);
        const finalValue = `${fromat[1]} ${fromat[2]}`;
        const regex = /^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]))))[0-9][A-Za-z]{2})$/i;
        return {
            isValid: regex.test(postcode),
            formatedPostCode: finalValue,
            error: false,
            info: 'It is a valid postcode'
        };
    } catch (error) {
        return { error: true , info: 'Invalid post code has been entered!'};
    }
};
valid_postcode('GU348RR')
result => {isValid: true, formatedPostCode: "GU34 8RR", error: false, info: "It is a valid postcode"}
valid_postcode('sdasd4746asd')
result => {error: true, info: "Invalid post code has been entered!"}
valid_postcode('787898523')
result => {error: true, info: "Invalid post code has been entered!"}
Aathi
quelle