web-dev-qa-db-fra.com

RegEx pour faire correspondre les codes postaux britanniques

Je suis après une regex qui validera un code postal britannique complexe complet uniquement dans une chaîne d'entrée. Tous les formulaires de codes postaux peu communs doivent être couverts ainsi que d'habitude. Par exemple:

Correspondances

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

pas de correspondance

  • aWC2H 7LT
  • WC2H 7LTa
  • WC2H

Comment résoudre ce problème?

166
Kieran Benton

Je recommanderais de jeter un coup d'oeil à la norme de données du gouvernement britannique pour les codes postaux [lien maintenant mort; archive de XML , voir Wikipedia pour discussion]. Il existe une brève description des données et le schéma XML attaché fournit une expression régulière. Ce n'est peut-être pas exactement ce que vous voulez, mais ce serait un bon point de départ. Le RegEx diffère légèrement du XML, puisqu'un caractère P en troisième position au format A9A 9AA est autorisé par la définition donnée.

Le RegEx fourni par le gouvernement britannique était:

([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})

Comme indiqué dans la discussion sur Wikipedia, cela autorisera certains codes postaux non réels (par exemple, ceux commençant par AA, ZY) et fournissant un test plus rigoureux que vous pourriez essayer.

181
marcj

Il semble que nous allons utiliser ^(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})$, qui est une version légèrement modifiée de celle proposée par Minglis ci-dessus.

Cependant, nous devrons examiner exactement quelles sont les règles, car les différentes solutions énumérées ci-dessus semblent appliquer des règles différentes en ce qui concerne les lettres autorisées.

Après quelques recherches, nous avons trouvé quelques informations supplémentaires. Apparemment, une page sur 'govtalk.gov.uk' vous indique une spécification de code postal govtalk-postcodes . Cela pointe vers un schéma XML à l'adresse XML Schema , qui fournit une instruction 'pseudo regex' des règles de code postal.

Nous avons pris cela et travaillé un peu pour nous donner l'expression suivante:

^((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}))$

Cela rend les espaces optionnels, mais vous limite à un espace (remplacez le '&' par '{0,} pour un nombre illimité d'espaces). Cela suppose que tout le texte doit être en majuscule.

Si vous souhaitez autoriser les minuscules, avec un nombre d'espaces quelconque, utilisez:

^(([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}))$

Cela ne couvre pas les territoires d'outre-mer et ne fait que renforcer le format, PAS l'existence de zones différentes. Il est basé sur les règles suivantes:

Peut accepter les formats suivants:

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

Où:

  • 9 peut être n'importe quel nombre à un chiffre.
  • A peut être n'importe quelle lettre sauf Q, V ou X.
  • B peut être n'importe quelle lettre sauf I, J ou Z.
  • C peut être n’importe quelle lettre sauf I, L, M, N, O, P, Q, R, V, X, Y ou Z.
  • D peut être n'importe quelle lettre sauf I, J ou Z.
  • E peut être n’importe quel A, B, E, H, M, N, P, R, V, W, X ou Y.
  • Z peut être n'importe quelle lettre sauf C, I, K, M, O ou V.

Meilleurs vœux

Colin

81
Colin

Il n’existe pas d’expression régulière complète de code postal au Royaume-Uni capable de valider un code postal. Vous pouvez vérifier que le code postal est au bon format en utilisant une expression régulière. non pas qu'il existe réellement.

Les codes postaux sont arbitrairement complexes et changent constamment. Par exemple, le code de sortie W1 n'a pas et ne peut jamais avoir tous les nombres compris entre 1 et 99, pour chaque zone de code postal.

Vous ne pouvez pas vous attendre à ce que ce qui existe actuellement soit vrai pour toujours. Par exemple, en 1990, le bureau de poste a décidé qu’Aberdeen commençait à être un peu encombré. Ils ont ajouté un 0 à la fin de AB1-5, ce qui en fait un AB10-50, puis ont créé un certain nombre de codes postaux entre ceux-ci.

Chaque fois qu'une nouvelle rue est construite, un nouveau code postal est créé. Cela fait partie du processus d'obtention de la permission de construire; les autorités locales sont obligées de tenir ces informations à jour avec la poste (même si elles le font toutes).

En outre, comme l'ont noté plusieurs autres utilisateurs, il existe des codes postaux spéciaux tels que Girobank, GIR 0AA et celui destiné aux lettres au père Noël, SAN TA1 - vous ne voulez probablement pas poster quoi que ce soit mais cela ne semble pas être couvert par une autre réponse.

Ensuite, il y a les codes postaux BFPO, qui sont maintenant changeant pour un format plus standard . Les deux formats vont être valables. Enfin, il y a les territoires d'outre-mer source Wikipedia.

 + ---------- + --------------------------------- ------------- + 
 | Code postal | Lieu | 
 + ---------- + ------------------------------- --------------- + 
 | AI-2640 | Anguilla | 
 | ASCN 1ZZ | Île de l'Ascension | 
 | STHL 1ZZ | Sainte-Hélène | 
 | TDCU 1ZZ | Tristan da Cunha | 
 | BBND 1ZZ | Territoire britannique de l'océan Indien | 
 | BIQQ 1ZZ | Territoire britannique antarctique | 
 | FIQQ 1ZZ | Îles Falkland | 
 | GX11 1AA | Gibraltar | 
 | PCRN 1ZZ | Îles Pitcairn | 
 | SIQQ 1ZZ | Géorgie du Sud et les îles Sandwich du Sud | 
 | TKCA 1ZZ | Îles Turks et Caicos | 
 + ---------- + -------------------------------- ------------------ +

Ensuite, vous devez tenir compte du fait que le Royaume-Uni a "exporté" son système de code postal vers de nombreux endroits dans le monde. Tout ce qui valide un code postal "Royaume-Uni" validera également les codes postaux d'un certain nombre d'autres pays.

Si vous voulez valider un code postal britannique, le moyen le plus sûr consiste à utiliser une recherche des codes postaux actuels. Il y a un certain nombre d'options:

  • Communiqués Ordnance Survey Code-Point Open sous une licence de données ouverte. Ce sera très légèrement en retard, mais c'est gratuit. Cela n'inclura (probablement - je ne me souviens plus) d’informations relatives à l’Irlande du Nord, car l’Ordnance Survey n’a aucun mandat à cet égard. La cartographie en Irlande du Nord est réalisée par l'Ordnance Survey of Northern Ireland et ils ont leur produit, séparé, payant, Pointer . Vous pouvez utiliser ceci et ajouter les quelques-uns qui ne sont pas couverts assez facilement.

  • Royal Mail publie le fichier d'adresse de code postal (PAF) , cela inclut BFPO, ce que je ne suis pas sûr de savoir que Code-Point Open ouvre Il est mis à jour régulièrement, mais coûte de l'argent (et parfois, il peut être très méchant). PAF inclut l'adresse complète plutôt que de simples codes postaux et est accompagné de son propre Guide du programmeur . Le groupe d'utilisateurs de données ouvertes (ODUG) fait actuellement pression pour que PAF soit libéré gratuitement, voici une description de leur position .

  • Enfin, il y a AddressBase . Il s’agit d’une collaboration entre Ordnance Survey, les autorités locales, Royal Mail et une société correspondante afin de créer un répertoire définitif de toutes les informations sur toutes les adresses britanniques (elles ont également connu un assez bon succès). C'est payé, mais si vous travaillez avec une autorité locale, un ministère ou un service gouvernemental, son utilisation est gratuite. Il y a beaucoup plus d'informations que les codes postaux inclus.

42
Ben

J'ai récemment posté ne réponse à cette question sur les codes postaux britanniques pour la langue R . J'ai découvert que le modèle de regex du gouvernement britannique est incorrect et ne réussit pas à correctement valider certains codes postaux. Malheureusement, beaucoup de réponses ici sont basées sur ce schéma incorrect.

Je vais décrire ci-dessous certaines de ces questions et fournir une expression régulière révisée qui en fait.


Remarque

Ma réponse (et les expressions régulières en général):

  • Valide uniquement le code postal formats.
  • Ne garantit pas qu'un code postal existe légitimement.
    • Pour cela, utilisez une API appropriée! Voir réponse de Ben pour plus d'informations.

Si vous ne vous souciez pas de la mauvaise expression rationnelle et que vous voulez simplement passer à la réponse, faites défiler vers le bas Réponse section.

La mauvaise regex

Les expressions régulières de cette section ne doivent pas être utilisées.

C'est le regex défaillant que le gouvernement britannique a fourni aux développeurs (vous ne savez pas combien de temps ce lien sera actif, mais vous pouvez le voir dans leur documentation de Bulk Data Transfer ):

^([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})$

Problèmes

Problème 1 - Copier/coller

Voir l'expression rationnelle utilisée ici .

Comme beaucoup de développeurs le font probablement, ils copient/collent du code (en particulier des expressions régulières) et les collent en les attendant. Bien que ce soit formidable en théorie, cela échoue dans ce cas particulier, car copier/coller à partir de ce document modifie en fait l'un des caractères (un espace) en un caractère de nouvelle ligne, comme indiqué ci-dessous:

^([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})$

La première chose à faire par la plupart des développeurs est d’effacer la nouvelle ligne sans y penser à deux fois. Maintenant, la regex ne correspondra pas aux codes postaux contenant des espaces (autres que le GIR 0AA code postal).

Pour résoudre ce problème, le caractère de nouvelle ligne doit être remplacé par le caractère d'espace:

^([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})$
                                                                                                                                                     ^

Problème 2 - Limites

Voir l'expression rationnelle utilisée ici .

^([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})$
^^                     ^ ^                                                                                                                                            ^^

La regex de code postal ancre correctement la regex. Toute personne utilisant cette expression rationnelle pour valider des codes postaux pourrait être surprise si une valeur telle que fooA11 1AA passe à travers. C'est parce qu'ils ont ancré le début de la première option et la fin de la deuxième option (indépendamment l'un de l'autre), comme indiqué dans la regex ci-dessus.

Cela signifie que ^ _ (affirme la position au début de la ligne) ne fonctionne que sur la première option ([Gg][Ii][Rr] 0[Aa]{2}), la seconde option validera donc toutes les chaînes qui se terminent par un code postal (indépendamment de ce qui vient avant).

De même, la première option n'est pas ancrée à la fin de la ligne $, alors GIR 0AAfoo est également accepté.

^([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})$

Pour résoudre ce problème, les deux options doivent être encapsulées dans un autre groupe (ou un groupe ne faisant pas de capture) et les ancres placées autour de celui-ci:

^(([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}))$
^^                                                                                                                                                                      ^^

Problème 3 - Mauvais jeu de caractères

Voir l'expression rationnelle utilisée ici .

^([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})$
                                                                                       ^^

Il manque un regex - ici pour indiquer une plage de caractères. Tel quel, si un code postal est au format ANA NAA (où A représente une lettre et N représente un nombre) et commence par autre chose que A ou Z, il échouera.

Cela signifie que cela va correspondre à A1A 1AA et Z1A 1AA, mais non B1A 1AA.

Pour résoudre ce problème, le caractère - devrait être placé entre A et Z dans le jeu de caractères correspondant:

^([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})$
                                                                                        ^

Problème 4 - Mauvais jeu de caractères facultatif

Voir l'expression rationnelle utilisée ici .

^([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})$
                                                                                                                                        ^

Je jure qu'ils n'ont même pas testé cette chose avant de la publier sur le Web. Ils ont rendu le mauvais jeu de caractères facultatif. Ils ont fait [0-9] option dans la quatrième sous-option de l’option 2 (groupe 9). Cela permet à l'expression régulière de faire correspondre les codes postaux mal formatés comme AAA 1AA.

Pour résoudre ce problème, rendez la classe de caractères suivante facultative à la place (puis définissez le jeu [0-9] _ ne correspond qu'une fois):

^([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})$
                                                                                                                                                ^

Problème 5 - Performance

Les performances sur cette expression rationnelle sont extrêmement médiocres. Tout d’abord, ils ont placé l’option de configuration la moins susceptible de correspondre à GIR 0AA au début. Combien d'utilisateurs auront probablement ce code postal par rapport à un autre code postal; probablement jamais? Cela signifie que chaque fois que l'expression rationnelle est utilisée, elle doit d'abord épuiser cette option avant de passer à l'option suivante. Pour voir comment les performances sont affectées, vérifiez le nombre de pas regex d'origine a pris (35) contre même regex après avoir inversé les options (22).

Le deuxième problème de performance est lié à la structure de la regex entière. Inutile de revenir sur chaque option si l’une échoue. La façon dont la regex actuelle est structurée peut être grandement simplifiée. Je propose un correctif dans la section Answer .

Problème 6 - Les espaces

Voir l'expression rationnelle utilisée ici

Cela peut ne pas être considéré comme un problème, en soi, mais cela suscite des inquiétudes pour la plupart des développeurs. Les espaces dans l'expression régulière ne sont pas facultatifs, ce qui signifie que les utilisateurs qui entrent leur code postal doivent placer un espace dans le code postal. C'est une solution facile en ajoutant simplement ? après les espaces pour les rendre facultatifs. Voir la section Réponse pour un correctif.


Répondre

1. Corriger le regex du gouvernement britannique

La résolution de tous les problèmes décrits dans la section Problèmes et la simplification du modèle génèrent le modèle suivant, plus court et plus concis. Nous pouvons également supprimer la plupart des groupes puisque nous validons le code postal dans son ensemble (pas des parties individuelles):

Voir l'expression rationnelle utilisée ici

^([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})$

Cela peut encore être raccourci en supprimant toutes les plages de l'un des cas (majuscules ou minuscules) et en utilisant un drapeau ne respectant pas la casse. Remarque : Certaines langues n'en ont pas, utilisez donc la plus longue ci-dessus. Chaque langue implémente différemment l'indicateur d'insensibilité à la casse.

Voir l'expression rationnelle utilisée ici .

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

Plus court encore remplaçant [0-9] avec \d _ (si votre moteur regex le supporte):

Voir l'expression rationnelle utilisée ici .

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

2. Schémas simplifiés

Sans garantir des caractères alphabétiques spécifiques, vous pouvez utiliser les éléments suivants (n'oubliez pas les simplifications de 1. La correction de l'expression rationnelle du gouvernement britannique a également été appliquée ici):

Voir l'expression rationnelle utilisée ici .

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

Et même plus loin si vous ne vous souciez pas du cas particulier GIR 0AA:

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

3. Modèles compliqués

Je ne suggérerais pas une vérification excessive d'un code postal, de nouvelles zones, districts et sous-districts pouvant apparaître à tout moment. Ce que je vais suggérer potentiellement faire, est un support supplémentaire pour Edge-cases. Certains cas spéciaux existent et sont décrits dans cet article de Wikipedia .

Voici des expressions rationnelles complexes comprenant les sous-sections de 3. (3.1, 3.2, 3.3).

En relation avec les modèles dans 1. Correction du regex du gouvernement britannique :

Voir l'expression rationnelle utilisée ici

^(([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)$

Et par rapport à 2. Schémas simplifiés :

Voir l'expression rationnelle utilisée ici

^(([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 Territoires britanniques d'outre-mer

L'article de Wikipedia indique actuellement (certains formats légèrement simplifiés):

  • AI-1111: Anguila
  • ASCN 1ZZ: Île de l'Ascension
  • STHL 1ZZ: Sainte-Hélène
  • TDCU 1ZZ: Tristan da Cunha
  • BBND 1ZZ: Territoire britannique de l'océan Indien
  • BIQQ 1ZZ: Territoire britannique antarctique
  • FIQQ 1ZZ: Les îles Falkland
  • GX11 1ZZ: Gibraltar
  • PCRN 1ZZ: Iles Pitcairn
  • SIQQ 1ZZ: Géorgie du Sud et îles Sandwich du Sud
  • TKCA 1ZZ: Îles Turques-et-Caïques
  • BFPO 11: Akrotiri et Dhekelia
  • ZZ 11 & GE CX: Bermudes (selon ce document )
  • KY1-1111: Îles Caïmans (selon ce document )
  • VG1111: Iles Vierges britanniques (selon ce document )
  • MSR 1111: Montserrat (selon ce document )

Un regex complet englobant uniquement les territoires d'outre-mer britanniques pourrait ressembler à ceci:

Voir l'expression rationnelle utilisée ici .

^((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 Bureau de poste des forces britanniques

Bien qu'ils aient été récemment modifiés, il est mieux adapté au système de code postal britannique pour BF# (où # représente un nombre), ils sont considérés autres codes postaux optionnels. Ces codes postaux suivent le format de BFPO, suivi de 1 à 4 chiffres:

Voir l'expression rationnelle utilisée ici

^BFPO ?\d{1,4}$

3.3 Père Noël?

Il y a un autre cas spécial avec le père Noël (comme mentionné dans d'autres réponses): SAN TA1 est un code postal valide. Une regex pour cela est très simplement:

^SAN ?TA1$
35
ctwheels

J'ai jeté un coup d'œil à certaines des réponses ci-dessus et je recommande de ne pas utiliser le modèle de @ Dan's answer (c. 15 '10) , car il signale à tort près de 0,4% des codes postaux valides comme invalide, les autres non.

Ordnance Survey fournit un service appelé Code Point Open qui:

contient une liste de toutes les unités de code postal actuelles en Grande-Bretagne

J'ai exécuté chacune des expressions rationnelles ci-dessus sur la liste complète des codes postaux (6 juillet 2013) à partir de ces données en utilisant 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"

Il y a 1 686 202 codes postaux au total.

Vous trouverez ci-dessous le nombre de codes postaux valides ne correspondant pas à chaque $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

Bien entendu, ces résultats ne concernent que les codes postaux valides qui sont incorrectement marqués comme non valides. Alors:

'^.*$'
# => 0

Je ne dis rien sur le meilleur modèle en ce qui concerne le filtrage des codes postaux invalides.

20
RichardTowers
^([A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA)$

Expression régulière pour correspondre aux codes postaux britanniques valides. Dans le système postal britannique, toutes les lettres ne sont pas utilisées dans toutes les positions (la même chose que les plaques d'immatriculation des véhicules) et diverses règles régissent cette utilisation. Cette regex prend en compte ces règles. Détails des règles: Première moitié du code postal Formats valides [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] Position d'exception - Premier. Contraint - QVX non utilisé Position - Second. Contrainte - IJZ non utilisée sauf dans la RDA 0AA - Troisième position. Contrainte - AEHMNPRTVXY utilisé uniquement Position - Forth. Contraint - ABEHMNPRVWXY Seconde moitié du code postal Formats valides [0-9] [A-Z] [A-Z] Position d'exception - Deuxième et troisième. Contraint - CIKMOV non utilisé

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

17
Dan

La plupart des réponses ici ne fonctionnent pas pour tous les codes postaux que j'ai dans ma base de données. J'ai finalement trouvé celui qui valide avec tous, en utilisant la nouvelle expression régulière fournie par le gouvernement:

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

Il ne figure dans aucune des réponses précédentes et je le poste ici au cas où ils enlèveraient le lien:

^([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})$

MISE À JOUR: regex mis à jour comme indiqué par Jamie Bull. Je ne sais pas si c'était une erreur de copie ou une erreur dans la regex du gouvernement, le lien est en panne maintenant ...

UPDATE: Comme ctwheels l’a trouvé, cette expression rationnelle fonctionne avec la version javascript regex. Voir son commentaire pour celui qui fonctionne avec la saveur de pcre (php).

14
Jesús Carrera

Selon ce tableau Wikipedia

enter image description here

Ce modèle couvre tous les cas

(?:[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})

Si vous l’utilisez sur Android\Java, utilisez \\ d

12
AntPachon

Un ancien post mais toujours assez élevé dans les résultats de Google alors pensé que je mettrais à jour. Ce document du 14 octobre définit l’expression régulière de code postal britannique comme suit:

^([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})$

de:

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

Le document explique également la logique derrière cela. Cependant, il comporte une erreur (en gras) et autorise également les minuscules, qui bien que légalement n’est pas habituel, mais la version ainsi modifiée:

^(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})$

Cela fonctionne avec les nouveaux codes postaux de Londres (par exemple, W1D 5LH), contrairement aux versions précédentes.

12
deadcrab

Ceci est la regex Google sert sur leur i18napis.appspot.com domaine:

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}
10
Alix Axel

Les codes postaux sont sujets à changement, et le seul véritable moyen de valider un code postal est de disposer de la liste complète des codes postaux et de voir si elle existe.

Mais les expressions régulières sont utiles car elles:

  • sont faciles à utiliser et à mettre en œuvre
  • sont court
  • sont rapides à courir
  • sont assez faciles à gérer (comparé à une liste complète de codes postaux)
  • toujours attraper la plupart des erreurs d'entrée

Mais les expressions régulières ont tendance à être difficiles à conserver, en particulier pour quelqu'un qui ne l'a pas inventé en premier lieu. Donc ça doit être:

  • aussi facile à comprendre que possible
  • preuve relativement future

Cela signifie que la plupart des expressions régulières dans cette réponse ne sont pas assez bonnes. Par exemple. Je peux voir ça [A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRV-Y] va correspondre à une zone de code postal de la forme AA1A - mais cela posera problème si et quand une nouvelle zone de code postal est ajoutée, car il est difficile de comprendre quelles zones de code postal correspondent.

Je souhaite également que mon expression régulière corresponde à la première et à la seconde moitié du code postal sous forme de correspondances entre parenthèses.

Donc, je suis venu avec ceci:

(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})

Au format PCRE, il est possible d’écrire comme suit:

/^
  ( 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

Pour moi, c'est le bon équilibre entre valider autant que possible, tout en préservant l'avenir et en facilitant la maintenance.

10
andre

Je cherchais un regex de code postal britannique au cours des derniers jours et je suis tombé sur ce fil. J’ai travaillé sur la plupart des suggestions ci-dessus et aucune d’entre elles n’a fonctionné pour moi. J’ai donc créé ma propre regex qui, à ma connaissance, capture tous les codes postaux britanniques valables à compter de janvier 2013 (selon les dernières publications de la poste royale).

La regex et quelques vérifications simples du code postal PHP le code est affiché ci-dessous. REMARQUE: - Il autorise les codes postaux inférieurs ou majuscules et l'anomalie GIR 0AA, mais permet de traiter la présence plus que probable d'un espace au milieu d'un code postal entré utilise également un simple str_replace pour supprimer l'espace avant de tester contre la regex. Toute différence au-delà de cela et le Royal Mail ne les mentionne même pas dans leur littérature (voir http://www.royalmail.com/sites/default/files/docs/pdf/programmers_guide_edition_7_v5.pdf et commencez à lire à partir de la page 17)!

Remarque: Dans la littérature de Royal Mail (lien ci-dessus), il existe une légère ambiguïté autour des 3ème et 4ème positions et des exceptions en place si ces caractères sont des lettres. J'ai contacté Royal Mail directement pour éclaircir et dans leurs propres mots "Une lettre à la 4ème position du code de sortie au format AANA NAA ne fait pas exception et les exceptions de 3ème position ne s'appliquent qu'à la dernière lettre du code de sortie avec le format ANA NAA. " Tout droit de la bouche du cheval!

<?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>";

    }

?>

J'espère que cela aidera tous les autres utilisateurs de ce fil à la recherche d'une solution.

9
Dan Solo

Voici une expression rationnelle basée sur le format spécifié dans les documents liés à la réponse de marcj:

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

La seule différence entre cela et les spécifications est que les 2 derniers caractères ne peuvent pas être dans [CIKMOV] selon les spécifications.

Edit: Voici une autre version qui teste les limitations de caractères de fin.

/^[A-Z]{1,2}[0-9][0-9A-Z]? ?[0-9][A-BD-HJLNP-UW-Z]{2}$/
7
Will Tomlins

Certaines des expressions rationnelles ci-dessus sont un peu restrictives. Notez que le code postal authentique: "W1K 7AA" échouerait étant donné la règle "Position 3 - AEHMNPRTVXY uniquement utilisé" ci-dessus, car "K" ne serait pas autorisé.

la 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})$

Cela semble un peu plus précis, voir le article de Wikipedia intitulé "Codes postaux au Royaume-Uni" .

Notez que cette expression régulière nécessite uniquement des caractères majuscules.

La plus grande question est de savoir si vous limitez la saisie utilisateur à autoriser uniquement les codes postaux existants ou si vous essayez simplement d'empêcher les utilisateurs d'entrer des déchets complets dans les champs du formulaire. Faire correspondre correctement tous les codes postaux possibles et le vérifier pour le futur est un casse-tête plus difficile et ne vaut probablement pas la peine si vous n'êtes pas HMRC.

5
minglis

J'utilise les expressions rationnelles suivantes que j'ai testées par rapport à tous les codes postaux britanniques valides. Il est basé sur les règles recommandées, mais est condensé autant que raisonnable et ne fait pas appel à des règles de regex spécifiques à un langage particulier.

([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})

Cela suppose que le code postal a été converti en majuscule et qu'il ne comporte pas de caractères de fin ni de fin, mais qu'il accepte un espace facultatif entre le code de sortie et le code.

Le code postal spécial "GIR0 0AA" est exclu et ne sera pas validé car il ne figure pas dans la liste officielle des codes postaux du bureau de poste et, autant que je sache, ne sera pas utilisé comme adresse enregistrée. L'ajouter devrait être trivial comme cas particulier si nécessaire.

4
Chisel

Règles de base:

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

Les codes postaux du Royaume-Uni (ou les codes postaux, comme on les appelle) sont composés de cinq à sept caractères alphanumériques séparés par un espace. Les règles concernant les personnages pouvant apparaître à des positions particulières sont plutôt compliquées et comportent des exceptions. L’expression régulière que nous venons de montrer s’en tient donc aux règles de base.

Règles complètes:

Si vous avez besoin d'une expression régulière qui coche toutes les cases des règles de code postal au détriment de la lisibilité, procédez comme suit:

^(?:(?:[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)$

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

Testé contre notre base de données clients et semble parfaitement précis.

4
Raphos

voici comment nous avons traité le problème du code postal britannique:

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

Explication:

  • attendez 1 ou 2 caractères a-z, amende supérieure ou inférieure
  • attendez 1 ou 2 chiffres
  • attendez 0 ou 1 caractère a-z, amende supérieure ou inférieure
  • espace optionnel autorisé
  • attendez 1 nombre
  • s'attendre à 2 a-z, amende supérieure ou inférieure

Cela obtient la plupart des formats, nous utilisons ensuite la base de données pour vérifier si le code postal est réel, ces données sont gérées par openpoint https://www.ordnancesurvey.co.uk/opendatadownload/products.html

j'espère que cela t'aides

3
Alex Stephens

Celui-ci autorise les espaces vides et les onglets des deux côtés au cas où vous ne voudriez pas échouer à la validation, puis le couper du côté droit.

^\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*$)
3
Matas Vaitkevicius

Première moitié du code postal Formats valides

  • [AZ] [AZ] [0-9] [AZ]
  • [AZ] [AZ] [0-9] [0-9]
  • [AZ] [0-9] [0-9]
  • [AZ] [AZ] [0-9]
  • [A-Z] [A-Z] [A-Z]
  • [A-Z] [0-9] [A-Z]
  • [AZ] [0-9]

Exceptions
Position 1 - QVX non utilisé
Position 2 - IJZ non utilisé sauf dans GIR 0AA
Position 3 - AEHMNPRTVXY utilisé uniquement
Position 4 - ABEHMNPRVWXY

Deuxième moitié du code postal

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

Exceptions
Position 2 + 3 - CIKMOV non utilisé

N'oubliez pas que tous les codes possibles ne sont pas utilisés. Cette liste est donc une condition nécessaire mais non suffisante pour un code valide. Il pourrait être plus facile de simplement faire correspondre une liste de tous les codes valides?

3
Martin Beckett

Pour vérifier si un code postal est dans un format valide, comme indiqué dans le Royal Mail guide du programmeur :

          |----------------------------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})$

Tous les codes postaux sur doogal.co.uk correspondent, à l'exception de ceux qui ne sont plus utilisés.

Ajout d'un ? après l’espace et en utilisant une correspondance insensible à la casse pour répondre à cette question:

'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" ]
3
Jackson Pauls

Je voulais une regex simple, où il est permis d’en autoriser trop, mais de ne pas refuser un code postal valide. Je suis allé avec ceci (l'entrée est une chaîne stripped/trimmed):

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

Les longueurs de 5 à 7 (sans compter les espaces) signifient que nous autorisons les codes postaux les plus courts possibles, tels que "L1 8JQ", ainsi que les plus longs, tels que "OL14 5ET".

EDIT: Changé le 8 en 7 afin que nous n'autorisons pas les codes postaux de 8 caractères.

3
Henrik N

Pour ajouter à cette liste une expression rationnelle plus pratique que j’utilise, qui permet à l’utilisateur de saisir un empty string est:

^$|^(([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}))$

Cette expression régulière autorise les majuscules et les minuscules avec un espace optionnel entre

Du point de vue des développeurs de logiciels, cette expression rationnelle est utile pour les logiciels où une adresse peut être facultative. Par exemple, si un utilisateur ne veut pas fournir ses détails d'adresse

2
user1

Regardez le code python sur cette page:

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

J'ai quelques analyses de code postal à faire. L'exigence est assez simple. Je dois analyser un code postal dans un code de sortie et un code (facultatif). La bonne nouvelle est que je n'ai pas à effectuer de validation - je dois juste découper ce que j'ai reçu d'une manière vaguement intelligente. Je ne peux pas assumer grand chose au sujet de mon importation en termes de formatage, c’est-à-dire les espaces et les espaces incorporés. Mais ce n'est pas la mauvaise nouvelle. la mauvaise nouvelle est que je dois tout faire en RPG. :-(

Néanmoins, j'ai jeté un peu Python fonctionner ensemble pour clarifier ma pensée.

Je l'ai utilisé pour traiter les codes postaux pour moi.

1
Rudiger Wolf

La réponse acceptée reflète les règles données par Royal Mail, bien qu'il y ait une faute de frappe dans la regex. Cette faute de frappe semble également être présente sur le site gov.uk (comme dans la page d'archive XML).

Dans le format A9A 9AA, les règles autorisent un caractère P en troisième position, ce que la regex ne permet pas. La regex correcte serait:

(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}) 

En raccourcissant le résultat, les expressions rationnelles suivantes (qui utilisent la syntaxe Perl/Ruby):

(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})

Il comprend également un espace optionnel entre les premier et deuxième blocs.

1
Stieb

Ce que j’ai trouvé dans presque toutes les variations et les expressions rationnelles du transfert en bloc pdf et de ce qui se trouve sur le site Wikipédia est le suivant, en particulier pour les expressions rationnelles wikipedia: il doit y avoir un ^ après le premier | (barre verticale). Je l'ai compris en testant AA9A 9AA, car sinon la vérification du format de A9A 9AA le validera. Par exemple, la vérification de EC1D 1BB qui doit être invalide revient valide car C1D 1BB est un format valide.

Voici ce que je propose pour une bonne regex:

^([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})$
1
Andrew Schliewe

On nous a donné une spec:

Les codes postaux britanniques doivent revêtir l'une des formes suivantes (à une exception près, voir ci-dessous): 
 § A9 9AA 
 § A99 9AA 
 § AA9 9AA 
 § AA99 9AA 
 § A9A 9AA 
 § AA9A 9AA 
 Où A représente un caractère alphabétique et 9, un caractère numérique. 
 Des règles supplémentaires s'appliquent aux caractères alphabétiques, comme suit: 
 § Le personnage en position 1 ne peut pas être Q, V ou X 
 § Le personnage en position 2 peut ne pas être I, J ou Z 
 § Le personnage en position 3 peut ne pas être I, L, M, N, O, P, Q, R, V, X, Y ou Z 
 § Le personnage en position 4 ne peut pas être C, D, F, G, I, J , K, L, O, Q, S, T, U ou Z 
 § Les caractères dans les deux positions les plus à droite peuvent ne pas être C, I, K, M, O ou V 
 Le code postal "GIR 0AA" est un code postal spécial valide, à l'exception de ces règles générales.

Nous avons eu ceci:

/^([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

Mais notez que cela permet un nombre illimité d'espaces entre les groupes.

1
paulslater19

J'ai la regex pour la validation du code postal britannique.

Cela fonctionne pour tout type de code postal interne ou externe

^((([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}))$

Cela fonctionne pour tout type de format.

Exemple:

AB10 --------------------> SEULEMENT POSTCODE POST

A1 1AA ------------------> COMBINAISON DE CODE POSTAL (EXTÉRIEUR ET INTÉRIEUR)

WC2A --------------------> OUTER

1
Swift-Master

La méthode ci-dessous vérifie le code postal et fournit des informations complètes

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!"}
0
Aathi

J'avais besoin d'une version qui fonctionnerait avec SAS avec le PRXMATCH et les fonctions associées, alors j'ai proposé ceci:

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

Cas de test et notes:

/* 
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;
0
user667489

Je l'ai volé dans un document XML et il semble couvrir tous les cas sans GIRO codé en dur:

%r{[A-Z]{1,2}[0-9R][0-9A-Z]? [0-9][A-Z]{2}}i

(Syntaxe Ruby avec ignore case)

0
Ghoti