RegEx pour les codes postaux britanniques correspondants

186

Je suis à la recherche d'une expression régulière qui validera un code postal britannique complet et complexe uniquement dans une chaîne d'entrée. Tous les formulaires de code postal inhabituels doivent être couverts ainsi que l'habituel. Par exemple:

Allumettes

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

Pas de correspondance

  • aWC2H 7LT
  • WC2H 7LTa
  • WC2H

Comment résoudre ce problème?

Kieran Benton
la source
2
@axrwkr qui n'a pas l'air utile
Kieran Benton
8
Validation du code postal au Royaume-Uni - JavaScript et PHP Je n'ai pas pu obtenir la réponse acceptée pour correspondre aux codes postaux valides, mais j'ai trouvé cela et cela correspond aux codes postaux valides. Pour la validation côté client, la version JavaScript peut être utilisée telle quelle, pour la validation côté serveur, la réécriture du JavaScript en C # est assez simple. Il reformate même le code postal pour avoir un espace, donc si vous entrez un code postal comme W1A1AA, en plus de le valider, il le reformatera en W1A 1AA. Il traite même des codes postaux inhabituels dans divers territoires britanniques.
2
Le lien fourni ne fonctionne pas pour les formats «AA1A 1AA». Référence: dhl.com.tw/content/dam/downloads/tw/express/forms/…
Anthony Scaife
1
Si vous souhaitez simplement valider un code postal, nous vous proposons un point de terminaison de l'API REST de validation gratuite (inscription requise) - developer.alliescomputing.com/postcoder-web-api/address-lookup/…
Stephen Keable
1
Bonne question. Je pense qu'il vaudrait la peine d'inclure un code postal du centre de Manchester tel que "M1 3HZ" dans votre liste d'exemples rares qui doivent correspondre. Beaucoup de gens ne connaissent pas les combinaisons de chiffres 1 lettre 1.
Martin Joiner

Réponses:

208

Je recommanderais de jeter un 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 joint 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, car 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 Wikipédia, cela autorisera certains codes postaux non réels (par exemple ceux commençant par AA, ZY) et ils fournissent un test plus rigoureux que vous pourriez essayer.

Brian Campbell
la source
52
Et ce reg ex avec un espace blanc optionnel entre les deux segments (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
7
Peut-être une bonne idée d'apporter la regex réelle à la réponse, car les pages semblent expirer chaque année ...
pauloya
7
Notez que cette expression régulière est pour XML Schema, qui est, évidemment, légèrement différente des autres saveurs de regex
artbristol
6
Je n'arrive pas à faire fonctionner cela en JavaScript. Cela fonctionne-t-il uniquement avec certains moteurs regex?
NickG
12
En fait, ils l'ont changé: Transfert de données en^([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})$
masse
85

On dirait 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 suggérée par Minglis ci-dessus.

Cependant, nous allons devoir examiner exactement quelles sont les règles, car les différentes solutions énumérées ci-dessus semblent appliquer des règles différentes quant aux lettres autorisées.

Après quelques recherches, nous avons trouvé plus d'informations. Apparemment, une page sur «govtalk.gov.uk» vous indique une spécification de code postal govtalk-postcodes . Cela pointe vers un schéma XML au niveau du schéma XML qui fournit une déclaration «pseudo regex» des règles de code postal.

Nous avons pris cela et y avons 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 facultatifs, mais vous limite à un espace (remplacez le «&» par «{0,} pour des espaces illimités). Il suppose que tout le texte doit être en majuscules.

Si vous souhaitez autoriser les minuscules, avec un nombre quelconque d'espaces, 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 applique uniquement 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 à l'exception de 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 l'un quelconque des 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

Colin
la source
2
Excellente réponse, j'ai ajouté dans les outre-mer^(([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
Pourquoi spécifier {0,}au lieu de *pour des espaces optionnels illimités?
Code Animal
76

Je récemment une réponse à cette question sur Royaume - Uni pour les codes postaux de la langue de R . J'ai découvert que le modèle de regex du gouvernement britannique est incorrect et ne valide pas correctement certains codes postaux. Malheureusement, la plupart des réponses ici sont basées sur ce modèle incorrect.

Je vais décrire certains de ces problèmes ci-dessous et fournir une expression régulière révisée qui fonctionne réellement .


Remarque

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

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

Si vous ne vous souciez pas de la mauvaise regex et que vous voulez simplement passer à la réponse, défiler jusqu'à la section Réponse .

Le mauvais 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 (je ne sais pas combien de temps ce lien sera actif, mais vous pouvez le voir dans leur documentation de transfert de données en masse ):

^([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 regex utilisé ici .

Comme de nombreux développeurs le font probablement, ils copient / collent du code (en particulier les expressions régulières) et les collent en attendant qu'ils fonctionnent. Bien que cela soit excellent en théorie, cela échoue dans ce cas particulier car le copier / coller à partir de ce document change 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 que la plupart des développeurs feront est simplement d'effacer la nouvelle ligne sans réfléchir à deux fois. Désormais, l'expression régulière ne correspondra pas aux codes postaux contenant des espaces (à partGIR 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 regex utilisé 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})$
^^                     ^ ^                                                                                                                                            ^^

L'expression régulière de code postal ancre incorrectement l'expression régulière. Quiconque utilise cette expression régulière pour valider les codes postaux pourrait être surpris si une valeur commefooA11 1AA que celle-ci passe. 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 l'expression régulière 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}), donc la deuxième option validera toutes les chaînes qui se terminent par un code postal (indépendamment de ce qui précède).

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

^([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 enveloppées dans un autre groupe (ou groupe non capturant) 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 - Jeu de caractères incorrect

Voir regex utilisé 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})$
                                                                                       ^^

Le regex manque un -ici pour indiquer une plage de caractères. En l'état, si un code postal est au format ANA NAA(où Areprésente une lettre et Nreprésente un nombre), et qu'il commence par autre chose que AouZ , il échouera.

Cela signifie qu'il correspondra à A1A 1AAet Z1A 1AA, mais pas B1A 1AA.

Pour résoudre ce problème, le caractère -doit être placé entre le Aet Zdans le jeu de caractères respectif:

^([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 - Jeu de caractères facultatif incorrect

Voir regex utilisé 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 facultatif le mauvais jeu de caractères. Ils ont fait l' [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 commeAAA 1AA .

Pour résoudre ce problème, rendez la classe de caractères suivante facultative à la place (et faites ensuite correspondre l'ensemble [0-9]exactement 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 régulière sont extrêmement médiocres. Tout d'abord, ils ont placé l'option de modèle la moins susceptible de correspondre GIR 0AAau début. Combien d'utilisateurs auront probablement ce code postal par rapport à tout autre code postal; probablement jamais? Cela signifie que chaque fois que l'expression régulière 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 d'étapes effectuées par l' expression régulière d' origine (35) par rapport à la même expression régulière après avoir inversé les options (22).

Le deuxième problème de performance est dû à la façon dont l'ensemble de l'expression régulière est structurée. Il est inutile de revenir en arrière sur chaque option si l'une d'entre elles échoue. La façon dont la regex actuelle est structurée peut être grandement simplifiée. Je propose un correctif pour cela dans la section Réponse .

Problème 6 - Espaces

Voir regex utilisé ici

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


Répondre

1. Correction de l'expression régulière du gouvernement britannique

La résolution de tous les problèmes décrits dans la section Problèmes et la simplification du modèle donnent 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 regex utilisé 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 être raccourci en supprimant toutes les plages de l'un des cas (majuscules ou minuscules) et en utilisant un indicateur insensible à la casse. Remarque : certaines langues n'en ont pas, utilisez donc la plus longue ci-dessus. Chaque langage implémente différemment l'indicateur d'insensibilité à la casse.

Voir regex utilisé ici .

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

Plus court à nouveau en remplaçant [0-9] par \d(si votre moteur regex le prend en charge):

Voir regex utilisé ici .

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

2. Modèles simplifiés

Sans garantir des caractères alphabétiques spécifiques, les éléments suivants peuvent être utilisés (gardez à l'esprit les simplifications de 1. La correction de l'expression régulière du gouvernement britannique a également été appliquée ici):

Voir regex utilisé ici .

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

Et encore plus 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 de sur-vérification d'un code postal car de nouvelles zones, districts et sous-districts peuvent apparaître à tout moment. Ce que je vous suggère potentiellement faire, est ajouté le support pour le bord-cas. Certains cas particuliers existent et sont décrits dans cet article de Wikipédia .

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

En ce qui concerne les modèles de 1. Correction de l'expression régulière du gouvernement britannique :

Voir regex utilisé 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. Modèles simplifiés :

Voir regex utilisé 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 antarctique britannique
  • FIQQ 1ZZ: Les îles Falkland
  • GX11 1ZZ: Gibraltar
  • PCRN 1ZZ: Îles 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: Iles Caïmans (selon ce document )
  • VG1111: Îles Vierges britanniques (selon ce document )
  • MSR 1111: Montserrat (d'après ce document )

Une expression régulière globale pour ne correspondre qu'aux territoires britanniques d'outre-mer pourrait ressembler à ceci:

Voir regex utilisé 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 pour mieux s'aligner sur le système de code postal britannique BF#(où #représente un nombre), ils sont considérés comme des codes postaux alternatifs facultatifs . Ces codes postaux suivent le format de BFPO, suivi de 1 à 4 chiffres:

Voir regex utilisé ici

^BFPO ?\d{1,4}$

3.3 Père Noël?

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

^SAN ?TA1$
ctwheels
la source
4
Les modèles simplifiés sont une très bonne option à utiliser. Je trouve qu'il est préférable de ne pas être trop restrictif avec une expression régulière, car vous devez ensuite vous assurer qu'elle est mise à jour avec tous les changements ou vous pourriez avoir des utilisateurs très en colère. Je pense qu'il est préférable de faire correspondre vaguement avec une expression régulière simplifiée pour éliminer les erreurs évidentes, puis appliquer des vérifications supplémentaires telles qu'une recherche d'adresse (ou un e-mail de confirmation dans le cas d'une expression régulière par courrier électronique) pour confirmer la validité.
James Coyle
2
Excellente analyse approfondie.
Steve
1
Réponse brillante à tant de niveaux. En fin de compte, je suis allé avec votre 2ème modèle simplifié. Comme j'ai en fait une base de données avec tous les codes postaux britanniques, j'ai juste besoin d'un premier passage pour voir si une chaîne d'adresse contient potentiellement un code postal valide, donc je ne me soucie pas des faux positifs (car la recherche réelle les extirpera) , mais je me soucie des faux négatifs. Et la vitesse compte aussi.
John Powell le
Il y a tellement de problèmes avec le système de code postal britannique, manifestement créé par un comité avant l'ère informatique, mais le problème de la longueur et des espaces variables est l'un des plus pernicieux. J'ai vu toutes sortes d'horreurs, y compris le remplissage de codes postaux comme E1 5JX à E1 5JX, c'est-à-dire avec trois espaces, de sorte qu'il s'aligne bien avec SW18 5HA dans Excel (insérer un logiciel de choix hideusement inapproprié pour la gestion des adresses). La seule solution sensée, à mon humble avis, est de supprimer tous les espaces, de sorte que le code postal soit une seule chaîne avant de se rapprocher de Elastic, Solr, Postgres, etc.
John Powell
45

Il n’existe pas d’expression régulière complète de code postal britannique capable de valider un code postal. Vous pouvez vérifier qu'un code postal est au format correct à l'aide d'une expression régulière; non pas qu'il existe réellement.

Les codes postaux sont arbitrairement complexes et en constante évolution. Par exemple, le code de sortie W1n'a pas et peut ne jamais avoir tous les nombres 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. À titre d'exemple, en 1990, la poste a décidé qu'Aberdeen devenait un peu bondée. Ils ont ajouté un 0 à la fin de AB1-5, ce qui en fait 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 l'autorisation de construire; les autorités locales sont tenues de tenir cette mise à jour auprès de la poste (pas qu'elles le fassent toutes).

De plus, comme l'ont noté un certain nombre d'autres utilisateurs, il y a les codes postaux spéciaux tels que Girobank, GIR 0AA et celui pour les lettres au Père Noël, SAN TA1 - vous ne voulez probablement rien y publier mais cela ne semble pas être couvert par toute autre réponse.

Ensuite, il y a les codes postaux BFPO, qui passent maintenant à un format plus standard . Les deux formats seront valides. Enfin, il y a la source des territoires d'outre-mer Wikipédia .

+ ---------- + -------------------------------------- -------- +
| Code postal | Localisation |
+ ---------- + -------------------------------------- -------- +
| 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 antarctique britannique |
| FIQQ 1ZZ | Iles Falkland |
| GX11 1AA | Gibraltar |
| PCRN 1ZZ | Îles Pitcairn |
| SIQQ 1ZZ | Géorgie du Sud et îles Sandwich du Sud |
| TKCA 1ZZ | Îles Turques et Caïques |
+ ---------- + -------------------------------------- -------- +

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

Si vous souhaitez valider un code postal britannique, le moyen le plus sûr de le faire est d'utiliser une recherche des codes postaux actuels. Il existe plusieurs options:

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

  • Royal Mail publie le fichier d'adresses de code postal (PAF) , cela inclut BFPO, ce que je ne suis pas sûr que Code-Point Open fasse. Il est mis à jour régulièrement mais coûte de l'argent (et ils peuvent parfois être carrément méchants à ce sujet). PAF inclut l'adresse complète plutôt que de simples codes postaux et est livré avec son propre guide des programmeurs . L'Open Data User Group (ODUG) fait actuellement pression pour que PAF soit publié 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 pour créer un annuaire définitif de toutes les informations sur toutes les adresses britanniques (elles ont également eu beaucoup de succès). C'est payant, mais si vous travaillez avec une autorité locale, un département gouvernemental ou un service gouvernemental, leur utilisation est gratuite. Il y a beaucoup plus d'informations que de simples codes postaux inclus.

Ben
la source
la recherche semble intéressante
SuperUberDuper
2
bien que ce ne soit pas la réponse recherchée par l'op, c'est probablement la plus utile. Cela m'encouragera à assouplir les règles de vérification que je vais appliquer.
John Hunt du
22

J'ai jeté un œil à certaines des réponses ci-dessus et je recommande de ne pas utiliser le modèle de la réponse de @ Dan (vers 15 décembre 2010) , car il signale à tort près de 0,4% des codes postaux valides comme invalides, tandis que les autres ne le font pas .

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 régulières ci-dessus par rapport à la liste complète des codes postaux (6 juillet 13) à 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 au total 1 686 202 codes postaux.

Voici les nombres de codes postaux valides qui ne correspondent pas à chacun $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 sûr, ces résultats ne concernent que les codes postaux valides qui sont incorrectement marqués comme non valides. Alors:

'^.*$'
# => 0

Je ne dis pas quel modèle est le meilleur pour filtrer les codes postaux invalides.

RichardTowers
la source
1
N'est-ce pas ce que je dis dans ma réponse et si vous empruntez la voie de la dépréciation, vous devriez probablement tout faire, et le tenir à jour si quelqu'un change sa réponse? Sinon, faites au moins référence à la date de la dernière modification de la réponse à laquelle vous l'avez prise afin que les gens puissent voir si elle a été modifiée depuis.
Ben
Bon point. Modifié en conséquence. Je pense que cela ajoute à la discussion de souligner que la plupart de ces modèles n'excluent aucun des codes CPO, mais que la réponse la plus votée (regex valide) le fait. Futurs lecteurs: sachez que mes résultats seront probablement dépassés.
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)$

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 pour les plaques d'immatriculation des véhicules) et diverses règles régissent cela. 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 des exceptions - Premier. Contrainte - QVX non utilisé Position - Seconde. Contrainte - IJZ non utilisé sauf en position GIR 0AA - Troisième. Contrainte - AEHMNPRTVXY n'a utilisé que Position - Forth. Contrainte - ABEHMNPRVWXY Seconde moitié du code postal Formats valides [0-9] [AZ] [AZ] Exceptions Position - Deuxième et troisième. Contrainte - CIKMOV non utilisé

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

Dan
la source
1
Je ne sais pas pourquoi les gens ont décliné cette réponse - c'est la bonne expression régulière
Ollie
Le regex ne fonctionne pas pour les codes postaux "YO31" et "YO31 1" dans Javscript.
Pratik Khadloya
9
Je ne pense pas que ce soit correct, car l'expression régulière donnée contredit la description et suggère que vous pouvez avoir des codes postaux commençant par 0-9, ce que vous ne pouvez pas
Luigi Plinge
4
Cette regex échoue sur environ 6000 codes postaux valides, je le déconseille donc. Voyez ma réponse .
RichardTowers
cela échoue sur n'importe quel code postal en minuscules ou sans espace pour moi
Dancer
14

Selon ce tableau Wikipedia

entrez la description de l'image ici

Ce motif 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})

Lors de son utilisation sur Android \ Java, utilisez \\ d

AntPachon
la source
J'ai trouvé que c'était la réponse la plus lisible, bien qu'elle ne recherche que la forme d'un code postal, plutôt que des codes valides réels selon les solutions qui prennent les informations du site Web gov.uk, mais cela suffit pour mon cas d'utilisation. Après avoir joué un peu avec (en python), je l'ai factorisé en une expression régulière un peu plus compacte mais équivalente qui permet également un espace optionnel: ([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

La plupart des réponses ici ne fonctionnaient pas pour tous les codes postaux que j'ai dans ma base de données. J'en ai finalement trouvé un qui valide avec tous, en utilisant la nouvelle regex 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

Ce n'est dans aucune des réponses précédentes, donc je le poste ici au cas où ils supprimeraient 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 mon erreur de copie ou si c'était une erreur dans l'expression régulière du gouvernement, le lien est maintenant en panne ...

MISE À JOUR: Comme ctwheels l'a trouvé, ce regex fonctionne avec la saveur javascript regex. Voir son commentaire pour celui qui fonctionne avec la saveur pcre (php).

Jesús Carrera
la source
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})$devrait être ^([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})$- repérez la différence ;-)
Jamie Bull
1
Sur place! J'ai mis à jour ma réponse. Merci!
Jesús Carrera
2
C'est la seule réponse ici qui a fonctionné dans regexr.com et Notepad ++. Bien que, je l'ai changé en ([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})(supprimé ^et $ajouté un ?après l'espace) pour que regexr.com trouve plus d'un résultat et pour les deux pour trouver un résultat qui n'a pas de séparateur d'espace.
mythofechelon
@ctwheels cette expression régulière est pour la saveur javascript. Si votre lien en échec, vous sélectionnez javascript, cela fonctionnera. C'est un super hic et je vais mettre à jour ma réponse.
Jesús Carrera
1
L'expression régulière publiée dans la documentation est intrinsèquement incorrecte. L'expression entière doit être enveloppée dans un groupe sans capture (?:), puis des ancres placées autour d'elle. Voyez-le échouer ici . Pour plus d'informations, consultez ma réponse 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})|(([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}))$est l'expression régulière corrigée.
ctwheels
12

Un vieux post mais toujours assez élevé dans les résultats Google, alors j'ai pensé que je mettrais à jour. Ce document du 14 octobre définit l'expression régulière du 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 sous-jacente. Cependant, il comporte une erreur (en gras) et autorise également les minuscules, ce qui, bien que légal, ne soit pas habituel, donc version 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) que les versions précédentes ne faisaient pas.

crabe mort
la source
Il semble que l'erreur que vous avez mise en évidence en gras a été corrigée dans le document, mais je préfère toujours votre expression régulière car elle est plus facile à lire.
Professeur de programmation
5
La seule chose que je dirais est de rendre l'espace facultatif en changeant l'espace en \ s? car l'espace n'est pas une exigence pour la lisibilité.
Professeur de programmation
L'expression régulière publiée dans la documentation est intrinsèquement incorrecte. L'expression entière doit être enveloppée dans un groupe sans capture (?:), puis des ancres placées autour d'elle. Voyez-le échouer ici . Pour plus d'informations, consultez ma réponse 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})|(([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}))$est l'expression régulière corrigée.
ctwheels
10

Voici le regex que Google sert sur son domaine i18napis.appspot.com :

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
la source
10

Les codes postaux sont sujets à changement, et la seule vraie façon de valider un code postal est d'avoir la liste complète des codes postaux et de voir si elle est là.

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 à entretenir (par rapport à une liste complète de codes postaux)
  • attrape toujours la plupart des erreurs de saisie

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

  • aussi simple que possible à comprendre
  • preuve relativement future

Cela signifie que la plupart des expressions régulières de cette réponse ne sont pas assez bonnes. Par exemple, je peux voir que[A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRV-Y] va correspondre à une zone de code postal de la forme AA1A - mais ce sera une douleur dans le cou si et quand une nouvelle zone de code postal est ajoutée, car il est difficile de comprendre à quelles zones de code postal elle correspond.

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.

Alors j'ai trouvé 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 peut s'é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 étant à l'épreuve du temps et en permettant une maintenance facile.

andre
la source
Je ne sais pas pourquoi vous avez voté contre - cela fonctionne avec tous les codes postaux valides que j'ai lancés et les espaces que beaucoup des réponses ci-dessus ne gèrent pas correctement. Quelqu'un voudrait-il expliquer pourquoi?
Jon
1
@Jon Cela correspond également lorsque d'autres caractères sont ajoutés au début ou à la fin, par exemple, aSW1A 1AAasfgpour moi (je n'ai pas voté contre, car il semble que cela puisse être corrigé facilement)
décvalte
9

Je cherchais un regex de code postal britannique depuis environ un jour et je suis tombé sur ce fil. J'ai parcouru la plupart des suggestions ci-dessus et aucune d'entre elles n'a fonctionné pour moi.J'ai donc proposé ma propre expression régulière qui, pour autant que je sache, capture tous les codes postaux britanniques valides à partir de janvier 13 (selon la dernière littérature de le Royal Mail).

Le regex et un simple code PHP de vérification du code postal sont publiés ci-dessous. REMARQUE: - Il permet les codes postaux minuscules ou majuscules et l'anomalie GIR 0AA, mais pour gérer la présence, plus que probable, d'un espace au milieu d'un code postal entré, il utilise également un simple str_replace pour supprimer l'espace avant de tester contre le regex. Toute divergence au-delà de cela et le Royal Mail lui-même ne les mentionnent même pas dans leur littérature (voir http://www.royalmail.com/sites/default/files/docs/pdf/programmers_guide_edition_7_v5.pdf et commencer à lire à partir de la page 17) !

Remarque: Dans la propre littérature du Royal Mail (lien ci-dessus), il existe une légère ambiguïté concernant les 3e et 4e positions et les exceptions en place si ces caractères sont des lettres. J'ai contacté Royal Mail directement pour clarifier et dans leurs propres mots "Une lettre en 4ème position du code sortant au format AANA NAA n'a pas d'exceptions et les exceptions en 3ème position s'appliquent uniquement à la dernière lettre du code sortant avec le format ANA NAA. " Directement 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 toute autre personne qui rencontre ce fil à chercher une solution.

Dan Solo
la source
1
Je serais curieux de savoir quels exemples de codes postaux échouaient à celui publié?
Zhaph - Ben Duguid
Je ne peux pas vous donner de code postal spécifique (sans avoir accès à la liste complète PAF) mais les codes postaux au format ANA NAA échoueraient potentiellement car les lettres P et Q sont autorisées en 3ème position et les codes postaux au format AANA NAA échouent également car la 4ème position autorise toutes les lettres (l'expression régulière donnée dans la réponse acceptée ci-dessus ne tient pas compte de l'un ou l'autre de ces éléments). Comme je l'ai dit, je ne fais que suivre les conseils actuels du Royal Mail - au moment de la réponse ci-dessus, peut-être que l'expression régulière était pleinement conforme.
Dan Solo
Merci pour la mise en garde - je peux voir que "P" semble avoir été ajouté comme acceptable en troisième position (à partir de votre document lié), mais pas Q - mais où lisez-vous que "la 4ème position autorise toutes les lettres"? Le document ne mentionne pas du tout la «quatrième position» pour autant que je puisse voir, donc je lirais cela comme «la troisième lettre indépendamment de la position réelle».
Zhaph - Ben Duguid le
1
Je viens de recevoir un mot de l'équipe d'assistance de Royal Mail et mon interprétation des règles est apparemment correcte. Une lettre en 4ème position du code sortant (par exemple AANA NAA) n'a pas d'exceptions et les exceptions en 3ème position s'appliquent uniquement à la dernière lettre (par exemple ANA NAA). Directement de la bouche du cheval.
Dan Solo
1
@DanSolo Cette expression régulière renverra une vraie correspondance pour la première moitié d'un code postal valide sans le code d'entrée, par exemple SW1Aou BD25sans la seconde moitié (ou du moins pour moi)
decvalts
7

Voici une regex basée sur le format spécifié dans les documents qui sont 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 des caractères de fin.

/^[A-Z]{1,2}[0-9][0-9A-Z]? ?[0-9][A-BD-HJLNP-UW-Z]{2}$/
Will Tomlins
la source
Il y a beaucoup plus de complexités dans un code postal britannique que d'accepter simplement A-Z- Qn'est jamais autorisé, Vn'est utilisé qu'avec parcimonie, etc. selon la position du caractère.
Zhaph - Ben Duguid
2
Cela n'a peut-être pas d'importance si vous voulez une vérification de syntaxe. Comme beaucoup d'autres l'ont fait remarquer, seule une recherche dans une base de données à jour devient presque correcte, et même dans ce cas, il y a le problème de la mise à jour de la base de données. Donc, pour moi, ce vérificateur de syntaxe regex est clair, simple et utile.
Rick-777
5

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

le 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 l'article de Wikipédia intitulé «Postcodes in the United Kingdom» .

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 pour n'autoriser que les codes postaux qui existent réellement ou si vous essayez simplement d'empêcher les utilisateurs de saisir des ordures complètes dans les champs du formulaire. Faire correspondre correctement tous les codes postaux possibles et les vérifier pour l'avenir est un casse-tête plus difficile, et ne vaut probablement pas la peine à moins que vous ne soyez HMRC.

minglis
la source
On dirait que le bureau de poste a évolué, mais le gouvernement est un peu à la traîne :(
Zhaph - Ben Duguid
4
J'utilise 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}) | (([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}) $ "Je l'aime parce qu'il autorise les majuscules et les minuscules et rend l'espace facultatif - meilleur pour la convivialité, sinon 100% correct!
bigtv
4

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 az, fin supérieur ou inférieur
  • attendez 1 ou 2 nombres
  • attendez 0 ou 1 az char, supérieur ou inférieur fin
  • espace optionnel autorisé
  • attendez 1 numéro
  • attendez 2 az, fin supérieur ou inférieur

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

J'espère que cela t'aides

Alex Stephens
la source
Cela autorise le format AANNA NAA, qui n'est pas valide.
ctwheels
D'où la partie «Cela obtient la plupart des formats» de la réponse. :)
Alex Stephens
4

Règles de base:

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

Les codes postaux au 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 couvrant les caractères pouvant apparaître à des positions particulières sont plutôt compliquées et pleines d'exceptions. L'expression régulière qui vient d'être affichée 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 pour les règles de code postal au détriment de la lisibilité, vous y allez:

^(?:(?:[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é par rapport à notre base de données clients et semble parfaitement précis.

Raphos
la source
4

J'utilise l'expression régulière suivante que j'ai testée avec tous les codes postaux britanniques valides. Il est basé sur les règles recommandées, mais condensé autant que raisonnable et n'utilise pas de 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})

Il suppose que le code postal a été converti en majuscules et n'a pas de caractères de début ou de fin, mais acceptera un espace facultatif entre le code externe et l'incode.

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 de la Poste et, à ma connaissance, ne sera pas utilisé comme adresse enregistrée. L'ajouter devrait être trivial en tant que cas spécial si nécessaire.

Ciseau
la source
4

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

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

Cela permet les codes postaux les plus courts possibles comme "L1 8JQ" ainsi que les plus longs comme "OL14 5ET".

Puisqu'il autorise jusqu'à 8 caractères, il autorisera également des codes postaux incorrects de 8 caractères s'il n'y a pas d'espace: "OL145ETX". Mais encore une fois, c'est une regex simpliste, pour quand c'est assez bon.

Henrik N
la source
Oh, mes excuses. Je pense que j'ai raté le / i lorsque je testais hier.
John
3

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]

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

Seconde 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 comparer avec une liste de tous les codes valides?

Martin Beckett
la source
3

Pour vérifier qu'un code postal est dans un format valide selon le guide du programmeur de Royal Mail :

          |----------------------------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.

Ajouter un ?après l'espace et utiliser 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" ]
Jackson Pauls
la source
3

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

^\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
la source
C'est le seul modèle qui a fonctionné pour moi en utilisant c # (System.Text.RegularExpressions) avec les exemples décrits dans la question originale
MattjeS
Il s'agit de l'expression rationnelle cassée du gouvernement britannique et elle ne valide pas certains des formats valides.
ctwheels
@ctwheels Bonjour, pourriez-vous s'il vous plaît fournir un code postal défaillant, merci.
Matas Vaitkevicius
Par exemple, ce AAA 1AAn'est pas un format valide: voir ma réponse pour une explication et une correction.
ctwheels
2

Pour ajouter à cette liste une expression régulière plus pratique que j'utilise et qui permet à l'utilisateur d'entrer un empty stringest:

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

Du point de vue des développeurs de logiciels, cette expression régulière est utile pour les logiciels où une adresse peut être facultative. Par exemple, si un utilisateur n'a pas souhaité fournir ses coordonnées

utilisateur1
la source
1

Jetez un œil au code python sur cette page:

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

J'ai une analyse de code postal à faire. L'exigence est assez simple; Je dois analyser un code postal en un outcode et un incode (facultatif). La bonne nouvelle est que je n'ai pas à effectuer de validation - je dois juste découper ce qui m'a été fourni d'une manière vaguement intelligente. Je ne peux pas assumer grand-chose sur mon import en termes de formatage, c'est-à-dire casse et espaces intégré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é une petite fonction Python ensemble pour clarifier ma pensée.

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

Rudiger Wolf
la source
1

On nous a donné une spécification:

Les codes postaux britanniques doivent être dans 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 représente un caractère numérique.
Des règles supplémentaires s'appliquent aux caractères alphabétiques, comme suit:
    § Le caractère en position 1 ne peut pas être Q, V ou X
    § Le caractère en position 2 ne peut pas être I, J ou Z
    § Le caractère en position 3 ne peut pas être I, L, M, N, O, P, Q, R, V, X, Y ou Z
    § Le caractère 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 ne peuvent pas être C, I, K, M, O ou V
La seule exception qui ne respecte pas ces règles générales est le code postal "GIR 0AA", qui est un code postal valide spécial.

Nous avons trouvé 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 - cela autorise n'importe quel nombre d'espaces entre les groupes.

paulslater19
la source
2
paulslater19, malheureusement votre solution autorise les codes postaux A99A 9AA.
1

J'ai le 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 tous les types de formats.

Exemple:

AB10 --------------------> UNIQUEMENT CODE POSTAL EXTERNE

A1 1AA ------------------> COMBINAISON DE CODE POSTAL (EXTERNE ET INTERNE)

WC2A --------------------> EXTÉRIEUR

Maître Swift
la source
1

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 l'expression régulière. Cette faute de frappe semble également avoir été 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, tandis que l'expression régulière ne le permet pas. Le regex correct 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}) 

Raccourcir cela aboutit à l'expression régulière suivante (qui utilise 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 facultatif entre le premier et le deuxième bloc.

Stieb
la source
1

Ce que j'ai trouvé dans presque toutes les variantes et les expressions régulières du pdf de transfert en masse et ce qui se trouve sur le site wikipedia est le suivant, en particulier pour le regex wikipedia, il doit y avoir un ^ après le premier | (barre verticale). J'ai compris cela en testant AA9A 9AA, car sinon le contrôle de format pour A9A 9AA le validera. Par exemple, la vérification de EC1D 1BB qui devrait être invalide revient valide car C1D 1BB est un format valide.

Voici ce que j'ai trouvé 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})$
Andrew Schliewe
la source
1

Grâce à des tests empiriques et à l'observation, ainsi qu'à la confirmation avec https://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom#Validation , voici ma version d'une expression régulière Python qui analyse et valide correctement un code postal britannique:

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

Cette regex est simple et comporte des groupes de capture. Il n'inclut pas toutes les validations des codes postaux légaux du Royaume-Uni, mais ne prend en compte que les positions des lettres et des chiffres.

Voici comment je l'utiliserais dans le code:

@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

Voici les tests unitaires:

@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
la source
0

J'avais besoin d'une version qui fonctionnerait en SAS avec les PRXMATCHfonctions et les fonctions associées, alors j'ai trouvé 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;
user667489
la source
0

La méthode ci-dessous vérifiera le code postal et fournira 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!"}
Aathi
la source