Codice postale Regno Unito Regex (completo)

Sono in procinto di un’espressione regolare che convaliderà un codice postale britannico complesso completo solo all’interno di una stringa di input. Tutti i moduli di codice postale non comuni devono essere coperti come al solito. Per esempio:

fiammiferi

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

Nessuna corrispondenza

  • aWC2H 7LT
  • WC2H 7LTa
  • WC2H

Ci sono delle regex ufficiali o semi-ufficiali in uso per questo genere di cose? Qualche altro consiglio su come formattare e archiviare questi in un database?

Consiglierei di dare un’occhiata al Data Standard del governo del Regno Unito per i codici postali [link now dead; archivio di XML , consultare Wikipedia per discussione]. C’è una breve descrizione dei dati e lo schema xml allegato fornisce un’espressione regolare. Potrebbe non essere esattamente quello che vuoi, ma sarebbe un buon punto di partenza. RegEx differisce leggermente dall’XML, poiché un carattere P in terza posizione nel formato A9A 9AA è consentito dalla definizione fornita.

La RegEx fornita dal governo del Regno Unito era:

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

Come indicato nella discussione di Wikipedia, ciò consentirà alcuni codici postali non reali (ad esempio quelli che iniziano con AA, ZY) e forniscono un test più rigoroso da provare.

Sembra che useremo ^(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})$ , che è una versione leggermente modificata di quello suggerito da Minglis sopra.

Tuttavia, dovremo investigare esattamente quali sono le regole, poiché le varie soluzioni elencate sopra sembrano applicare regole diverse su quali lettere sono consentite.

Dopo alcune ricerche, abbiamo trovato ulteriori informazioni. Apparentemente una pagina su ‘govtalk.gov.uk’ ti indirizza a un codice postale postcode di specifica del codice postale . Ciò fa riferimento a uno schema XML in XML Schema che fornisce una dichiarazione “pseudo regex” delle regole del codice postale.

L’abbiamo preso e ci abbiamo lavorato un po ‘per darci la seguente espressione:

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

Questo rende gli spazi opzionali, ma ti limita a uno spazio (sostituisci ‘&’ con ‘{0,} per spazi illimitati). Presume che tutto il testo deve essere maiuscolo.

Se vuoi consentire le lettere minuscole, con un numero qualsiasi di spazi, usa:

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

Questo non copre i territori d’oltremare e applica solo il formato, NON l’esistenza di aree diverse. Si basa sulle seguenti regole:

Può accettare i seguenti formati:

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

Dove:

  • 9 può essere un qualsiasi numero a una cifra.
  • A può essere una qualsiasi lettera ad eccezione di Q, V o X.
  • B può essere una qualsiasi lettera ad eccezione di I, J o Z.
  • C può essere una qualsiasi lettera ad eccezione di I, L, M, N, O, P, Q, R, V, X, Y o Z.
  • D può essere una qualsiasi lettera ad eccezione di I, J o Z.
  • E può essere uno qualsiasi di A, B, E, H, M, N, P, R, V, W, X o Y.
  • Z può essere una qualsiasi lettera ad eccezione di C, I, K, M, O o V.

Auguri

Colin

Non esiste una regolare espressione del codice postale nel Regno Unito che sia in grado di convalidare un codice postale. Puoi verificare che il codice postale sia nel formato corretto usando un’espressione regolare; non che in realtà esiste.

I codici postali sono arbitrariamente complessi e in continua evoluzione. Ad esempio, il codice di uscita W1 non ha, e potrebbe mai, avere ogni numero compreso tra 1 e 99, per ogni area di codice postale.

Non puoi aspettarti che cosa c’è attualmente per essere vero per sempre. Ad esempio, nel 1990, l’ufficio postale decise che Aberdeen era un po ‘affollata. Hanno aggiunto uno 0 alla fine di AB1-5 rendendolo AB10-50 e quindi creato un numero di codici postali tra questi.

Ogni volta che viene creata una nuova strada, viene creato un nuovo codice postale. Fa parte del processo per ottenere il permesso di build; le autorità locali sono obbligate a tenerlo aggiornato con l’ufficio postale (non che tutti lo facciano).

Inoltre, come notato da un certo numero di altri utenti, ci sono i codici postali speciali come Girobank, GIR 0AA e quello per le lettere a Santa, SAN TA1 – probabilmente non vuoi postare nulla ma non sembra essere coperto da qualsiasi altra risposta.

Poi, ci sono i codici postali BFPO, che ora stanno cambiando in un formato più standard . Entrambi i formati saranno validi. Infine, ci sono i territori d’oltremare fonte Wikipedia .

 + ---------- + -------------------------------------- -------- +
 |  CAP |  Posizione
 + ---------- + -------------------------------------- -------- +
 |  AI-2640 |  Anguilla |
 |  ASCN 1ZZ |  Isola dell'Ascensione |
 |  STHL 1ZZ |  Sant'Elena |
 |  TDCU 1ZZ |  Tristan da Cunha |
 |  BBND 1ZZ |  Territorio britannico dell'Oceano Indiano |
 |  BIQQ 1ZZ |  Territorio antartico britannico |
 |  FIQQ 1ZZ |  Isole Falkland |
 |  GX11 1AA |  Gibilterra |
 |  PCRN 1ZZ |  Isole Pitcairn |
 |  SIQQ 1ZZ |  Georgia del Sud e isole Sandwich meridionali |
 |  TKCA 1ZZ |  Isole Turks e Caicos |
 + ---------- + -------------------------------------- -------- + 

Successivamente, è necessario tenere conto del fatto che il Regno Unito ha “esportato” il proprio sistema di codici postali in molti luoghi del mondo. Qualsiasi cosa che convalida un codice postale “Regno Unito” convaliderà anche i codici postali di un certo numero di altri paesi.

Se si desidera convalidare un codice postale nel Regno Unito, il modo più sicuro per farlo è utilizzare una ricerca dei codici postali correnti. Ci sono un certo numero di opzioni:

  • Ordnance Survey rilascia Code-Point Open sotto una licenza open data. Sarà molto indietro rispetto ai tempi ma è gratuito. Questo (probabilmente – non ricordo) non includerà i dati dell’Irlanda del Nord in quanto l’Ordnance Survey non ha alcun mandato lì. La mapping nell’Irlanda del Nord è condotta dall’Ordnance Survey dell’Irlanda del Nord e hanno il loro prodotto Pointer , separato e pagato. Puoi usare questo e aggiungere quelli che non sono coperti abbastanza facilmente.

  • Royal Mail rilascia il PAF ( Postcode Address File) , questo include BFPO che non sono sicuro che Open di codice aperto faccia. È aggiornato regolarmente ma costa denaro (e possono essere decisamente mediocri a volte). PAF include l’indirizzo completo anziché solo i codici postali e viene fornito con la propria Guida ai programmatori . L’Open User User Group (ODUG) sta attualmente facendo pressioni per far rilasciare gratuitamente il PAF, ecco una descrizione della loro posizione .

  • Infine, c’è AddressBase . Si tratta di una collaborazione tra Ordnance Survey, Autorità locali, Royal Mail e una società di corrispondenza per creare una directory definitiva di tutte le informazioni su tutti gli indirizzi del Regno Unito (hanno avuto anche un discreto successo). È pagato ma se lavori con un’Autorità locale, un dipartimento governativo o un servizio governativo è gratuito per loro. Ci sono molte più informazioni che solo i codici postali inclusi.

Ho dato un’occhiata ad alcune delle risposte di cui sopra e mi raccomando di non usare il pattern della risposta di @ Dan (15 dicembre 10) , poiché erroneamente segnala quasi lo 0,4% dei codici postali validi come non validi, mentre gli altri no .

Ordnance Survey fornisce un servizio chiamato Code Point Open che:

contiene un elenco di tutte le unità di codice postale correnti in Gran Bretagna

Ho eseguito ciascuna delle regex sopra l’elenco completo dei codici postali (6 luglio 13) da questi dati utilizzando 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" 

Ci sono 1.686.202 codici postali totali.

I seguenti sono i numeri di codici postali validi che non corrispondono a ciascun $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 

Naturalmente, questi risultati riguardano solo codici postali validi contrassegnati erroneamente come non validi. Così:

 '^.*$' # => 0 

Non sto dicendo nulla su quale pattern è il migliore per quanto riguarda il filtraggio dei codici postali non validi.

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

Espressione regolare per abbinare codici postali UK validi. Nel sistema postale del Regno Unito non tutte le lettere sono usate in tutte le posizioni (lo stesso con le targhe automobilistiche) e ci sono varie regole per governarlo. Questa espressione regolare tiene conto di tali regole. Dettagli delle regole: Prima metà del codice postale Formati validi [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] Posizione eccezione – Prima. Controindicazioni – QVX non utilizzato Posizione – Secondo. Contraint – IJZ non usato tranne in posizione GIR 0AA – Terzo. Vincolo – AEHMNPRTVXY usato solo Posizione – Avanti. Contraint – ABEHMNPRVWXY Seconda metà del codice postale Formati validi [0-9] [AZ] [AZ] Posizione eccezioni – Secondo e terzo. Controindicazioni – CIKMOV non utilizzato

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

Un vecchio post ma ancora piuttosto alto nei risultati di Google, quindi ho pensato di aggiornarlo. Questo documento del 14 ottobre definisce l’espressione regolare del codice postale nel Regno Unito come:

 ^([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**az][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$ 

a partire dal:

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

Il documento spiega anche la logica dietro di esso. Tuttavia, ha un errore (in grassetto) e consente anche le minuscole, che sebbene non sia normale, la versione così modificata:

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

Funziona con i nuovi codici postali di Londra (ad es. W1D 5LH) che le versioni precedenti non avevano.

La maggior parte delle risposte qui non ha funzionato per tutti i codici postali che ho nel mio database. Finalmente ne ho trovato uno che convalida con tutti, usando la nuova regex fornita dal governo:

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

Non è in nessuna delle precedenti risposte, quindi le postò qui nel caso in cui prendessero il link in basso:

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

AGGIORNAMENTO: regex aggiornata come indicato da Jamie Bull. Non sono sicuro se fosse il mio errore di copia o si è verificato un errore nella regex del governo, il collegamento è inattivo ora …

AGGIORNAMENTO: Come abbiamo trovato le ctwheels, questa regex funziona con il sapore regex javascript. Vedi il suo commento per uno che funziona con il sapore di pcre (php).

Secondo questa tabella di Wikipedia

inserisci la descrizione dell'immagine qui

Questo modello copre tutti i casi

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

Quando lo si utilizza su Android \ Java usa \\ d

I codici postali sono soggetti a modifiche e l’unico vero modo di convalidare un codice postale è di avere l’elenco completo dei codici postali e vedere se è lì.

Ma le espressioni regolari sono utili perché:

  • sono facili da usare e implementare
  • sono corti
  • sono veloci da gestire
  • sono abbastanza facili da gestire (rispetto a un elenco completo di codici postali)
  • ancora cattura la maggior parte degli errori di input

Ma le espressioni regolari tendono ad essere difficili da mantenere, specialmente per qualcuno che non l’ha inventato in primo luogo. Quindi deve essere:

  • il più facile da capire ansible
  • prova relativamente futura

Ciò significa che la maggior parte delle espressioni regolari in questa risposta non sono abbastanza buone. Ad esempio, posso vedere che [A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRV-Y] sta per corrispondere a un’area del codice postale del modulo AA1A – ma sarà un dolore nel collo se e quando viene aggiunta una nuova area di codice postale, perché è difficile capire quali aree del codice postale corrispondono.

Voglio anche che la mia espressione regolare corrisponda alla prima e alla seconda parte del codice postale come corrispondenze tra parentesi.

Quindi mi sono inventato questo:

 (GIR(?=\s*0AA)|(?:[BEGLMNSW]|[AZ]{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}) 

Nel formato PCRE può essere scritto come segue:

 /^ ( GIR(?=\s*0AA) # Match the special postcode "GIR 0AA" | (?: [BEGLMNSW] | # There are 8 single-letter postcode areas [AZ]{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 

Per me questo è il giusto equilibrio tra la convalida il più ansible, mentre allo stesso tempo è a prova di futuro e consente una facile manutenzione.

Sono stato alla ricerca di una regex nel Regno Unito per l’ultimo giorno o giù di lì e sono incappato in questo thread. Ho lavorato sulla maggior parte dei suggerimenti di cui sopra e nessuno di loro ha funzionato per me, così ho scoperto la mia regex che, per quanto ne so, cattura tutti i codici postali del Regno Unito validi a partire dal 13 gennaio (secondo l’ultima letteratura di la Royal Mail).

Di seguito è riportata la regex e qualche semplice codice postale che controlla il codice PHP. NOTA: – Permette il postcode di maiuscole o minuscole e l’anomalia di GIR 0AA ma per gestire la presenza più che probabile di uno spazio nel mezzo di un codice postale inserito, fa anche uso di un semplice str_replace per rimuovere lo spazio prima di testare contro la regex. Eventuali discrepanze oltre a ciò e la stessa Royal Mail non le menzionano nemmeno nella loro letteratura (vedi http://www.royalmail.com/sites/default/files/docs/pdf/programmers_guide_edition_7_v5.pdf e inizia a leggere da pagina 17) !

Nota: nella letteratura della Royal Mail (link sopra) c’è una leggera ambiguità che circonda la 3a e la 4a posizione e le eccezioni sul posto se questi caratteri sono lettere. Ho contattato direttamente la Royal Mail per chiarirla e con le loro stesse parole “Una lettera nella 4a posizione del codice di uscita con il formato AANA NAA non ha eccezioni e le eccezioni di 3a posizione si applicano solo all’ultima lettera del codice di andata con il formattare ANA NAA. ” Direttamente dalla bocca del cavallo!

 "; } else { echo "$postcode2check is not a valid postcode
"; } ?>

Spero che aiuti chiunque altro che incontra questo thread alla ricerca di una soluzione.

Questa è un’espressione regolare che Google offre sul proprio dominio 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} 

Ecco una espressione regolare basata sul formato specificato nei documenti che sono collegati alla risposta di Marcj:

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

L’unica differenza tra questo e le specifiche è che gli ultimi 2 caratteri non possono essere in [CIKMOV] secondo le specifiche.

Modifica: ecco un’altra versione che verifica le limitazioni dei caratteri finali.

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

Alcune delle regex sopra riportate sono un po ‘restrittive. Nota il vero codice postale: “W1K 7AA” fallirebbe data la regola “Posizione 3 – AEHMNPRTVXY usata solo” sopra poiché “K” non sarebbe consentito.

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

Sembra un po ‘più accurato, vedi l’ articolo di Wikipedia intitolato “Codici postali nel Regno Unito” .

Si noti che questa espressione regolare richiede solo caratteri maiuscoli.

La domanda più importante è se si limitano gli input dell’utente per consentire solo i codici postali effettivamente esistenti o se si sta semplicemente tentando di impedire agli utenti di immettere spazzatura completa nei campi del modulo. Corrispondenza corretta di tutti i possibili codici postali e prove future è un enigma più difficile, e probabilmente non ne vale la pena a meno che non siate HMRC.

Regole di base:

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

I codici postali nel Regno Unito (o codici postali, come vengono chiamati) sono composti da cinque a sette caratteri alfanumerici separati da uno spazio. Le regole che coprono quali personaggi possono apparire in determinate posizioni sono piuttosto complicate e irte di eccezioni. L’espressione regolare appena mostrata si attacca quindi alle regole di base.

Regole complete:

Se hai bisogno di un’espressione regolare che tocchi tutte le caselle per le regole del codice postale a scapito della leggibilità, qui puoi:

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

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

Testato contro il database dei nostri clienti e sembra perfettamente accurato.

Prima metà del codice postale Formati validi

  • [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]

eccezioni
Posizione 1 – QVX non utilizzato
Posizione 2 – IJZ non utilizzato tranne in GIR 0AA
Posizione 3: solo AEHMNPRTVXY
Posizione 4 – ABEHMNPRVWXY

Seconda metà del codice postale

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

eccezioni
Posizione 2 + 3 – CIKMOV non utilizzato

Ricorda che non tutti i codici possibili sono usati, quindi questa lista è una condizione necessaria ma non sufficiente per un codice valido. Potrebbe essere più facile abbinare semplicemente un elenco di tutti i codici validi?

Per controllare un codice postale è in un formato valido secondo la guida del programmatore di 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][AZ]?|[1-9][0-9])|[1-9]([0-9]|[A-HJKPSTUW])?) [0-9][ABD-HJLNP-UW-Z]{2})$ 

Tutti i codici postali sulla partita di doogal.co.uk , ad eccezione di quelli non più in uso.

Aggiungere un ? dopo lo spazio e utilizzando la combinazione senza distinzione tra maiuscole e minuscole per rispondere a questa domanda:

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

Io uso il seguente regex che ho testato contro tutti i codici postali Regno Unito validi. Si basa sulle regole raccomandate, ma è sintetizzato quanto ragionevole e non fa uso di regole regex specifiche per la lingua.

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

Si presuppone che il codice postale sia stato convertito in maiuscolo e che non abbia caratteri iniziali o finali, ma accetti uno spazio opzionale tra l’outcode e l’incode.

Il codice postale speciale “GIR0 0AA” è escluso e non verrà convalidato poiché non è presente nell’elenco postale ufficiale dei codici postali e per quanto a mia conoscenza non verrà utilizzato come indirizzo registrato. Aggiungerlo dovrebbe essere banale come caso speciale se necessario.

Questo consente di lasciare spazi vuoti e tabs da entrambi i lati nel caso in cui non si voglia fallire la convalida e quindi tagliare il lato sever.

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

ecco come abbiamo affrontato il problema del codice postale nel Regno Unito:

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

Spiegazione:

  • aspettatevi 1 o 2 caratteri az, multa superiore o inferiore
  • aspettati 1 o 2 numeri
  • aspettarsi 0 o 1 carattere az, multa superiore o inferiore
  • spazio opzionale consentito
  • aspettati 1 numero
  • aspettatevi 2 az, multa superiore o inferiore

Questo ottiene la maggior parte dei formati, quindi usiamo il db per convalidare se il codice postale è effettivamente reale, questo dato è guidato da openpoint https://www.ordnancesurvey.co.uk/opendatadownload/products.html

spero che questo ti aiuti

Per aggiungere a questa lista una regex più pratica che uso che consente all’utente di inserire una empty string è:

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

Questo regex consente lettere maiuscole e minuscole con uno spazio opzionale in mezzo

Da un punto di vista degli sviluppatori di software, questa regex è utile per il software in cui un indirizzo può essere facoltativo. Ad esempio se un utente non desidera fornire i dettagli dell’indirizzo

Volevo una regex semplice, dove va bene concedere troppo, ma non negare un codice postale valido. Sono andato con questo (l’input è una stringa spogliata / tagliata):

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

Le lunghezze da 5 a 7 (senza contare gli spazi vuoti) significa che permettiamo i codici postali più brevi possibili come “L1 8JQ” e quelli più lunghi come “OL14 5ET”.

EDIT: cambiato l’8 in un 7 quindi non permettiamo codici postali di 8 caratteri.

Dai un’occhiata al codice Python in questa pagina:

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

Ho un po ‘di analisi del codice postale da fare. Il requisito è piuttosto semplice; Devo analizzare un codice postale in un codice esterno e (facoltativo) in codice. La buona notizia è che non devo eseguire alcuna convalida: devo solo abbattere ciò che mi è stato fornito in un modo vagamente intelligente. Non posso assumere molto sulla mia importazione in termini di formattazione, vale a dire caso e spazi incorporati. Ma questa non è la ctriggers notizia; la ctriggers notizia è che devo fare tutto in RPG. 🙁

Tuttavia, ho lanciato una piccola funzione Python per chiarire il mio pensiero.

L’ho usato per elaborare i codici postali per me.

Ci hanno dato una specifica:

  I codici postali del Regno Unito devono essere in uno dei seguenti moduli (con un'eccezione, vedi sotto): 
     § A9 9AA 
     § A99 9AA
     § AA9 9AA
     § AA99 9AA
     § A9A 9AA
     § AA9A 9AA
 dove A rappresenta un carattere alfabetico e 9 rappresenta un carattere numerico.
 Ulteriori regole si applicano ai caratteri alfabetici, come segue:
     § Il personaggio in posizione 1 potrebbe non essere Q, V o X
     § Il personaggio in posizione 2 potrebbe non essere I, J o Z
     § Il personaggio in posizione 3 non può essere I, L, M, N, O, P, Q, R, V, X, Y o Z
     § Il personaggio in posizione 4 potrebbe non essere C, D, F, G, I, J, K, L, O, Q, S, T, U o Z
    § The characters in the rightmost two positions may not be C, I, K, M, O or V
The one exception that does not follow these general rules is the postcode "GIR 0AA", which is a special valid postcode. 

We came up with this:

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

But note – this allows any number of spaces in between groups.

I have the regex for UK Postcode validation.

This is working for all type of Postcode either inner or outer

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

This is working for all type of format.

Esempio:

AB10——————–>ONLY OUTER POSTCODE

A1 1AA——————>COMBINATION OF (OUTER AND INNER) POSTCODE

WC2A——————–>OUTER

The accepted answer reflects the rules given by Royal Mail, although there is a typo in the regex. This typo seems to have been in there on the gov.uk site as well (as it is in the XML archive page).

In the format A9A 9AA the rules allow a P character in the third position, whilst the regex disallows this. The correct regex would be:

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

Shortening this results in the following regex (which uses Perl/Ruby syntax):

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

It also includes an optional space between the first and second block.

here you can find a few helpful links, depends on what language you are using:

http://www.ukpostcode.net/wiki/develop

What i have found in nearly all the variations and the regex from the bulk transfer pdf and what is on wikipedia site is this, specifically for the wikipedia regex is, there needs to be a ^ after the first |(vertical bar). I figured this out by testing for AA9A 9AA, because otherwise the format check for A9A 9AA will validate it. For Example checking for EC1D 1BB which should be invalid comes back valid because C1D 1BB is a valid format.

Here is what I’ve come up with for a good regex:

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

I recently posted an answer to this question on UK postcodes for the R language . I discovered that the UK Government’s regex pattern is incorrect and fails to properly validate some postcodes. Unfortunately, many of the answers here are based on this incorrect pattern.

I’ll outline some of these issues below and provide a revised regular expression that actually works.


Nota

My answer (and regular expressions in general):

  • Only validates postcode formats .
  • Does not ensure that a postcode legitimately exists .
    • For this, use an appropriate API! See Ben’s answer for more info.

The Bad Regex

The regular expressions in this section should not be used.

This is the failing regex that the UK government has provided developers (not sure how long this link will be up, but you can see it in their Bulk Data Transfer documentation ):

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

Problem 1 – Copy/Paste

See regex in use here .

As many developers likely do, they copy/paste code (especially regular expressions) and paste them expecting them to work. While this is great in theory, it fails in this particular case because copy/pasting from this document actually changes one of the characters (a space) into a newline character as shown below:

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

The first thing most developers will do is just erase the newline without thinking twice. Now the regex won’t match postcodes with spaces in them (other than the GIR 0AA postcode).

To fix this issue, the newline character should be replaced with the space character:

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

Problem 2 – Boundaries

See regex in use here .

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

The postcode regex improperly anchors the regex. Anyone using this regex to validate postcodes might be surprised if a value like fooA11 1AA gets through. That’s because they’ve anchored the start of the first option and the end of the second option (independently of one another), as pointed out in the regex above.

What this means is that ^ (asserts position at start of the line) only works on the first option ([Gg][Ii][Rr] 0[Aa]{2}) , so the second option will validate any strings that end in a postcode (regardless of what comes before).

Similarly, the first option isn’t anchored to the end of the line $ , so GIR 0AAfoo is also accepted.

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

To fix this issue, both options should be wrapped in another group (or non-capturing group) and the anchors placed around that:

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

Problem 3 – Improper Character Set

See regex in use here .

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

The regex is missing a - here to indicate a range of characters. As it stands, if a postcode is in the format ANA NAA (where A represents a letter and N represents a number), and it begins with anything other than A or Z , it will fail.

That means it will match A1A 1AA and Z1A 1AA , but not B1A 1AA .

To fix this issue, the character - should be placed between the A and Z in the respective character set:

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

Problem 4 – Wrong Optional Character Set

See regex in use here .

 ^([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 swear they didn’t even test this thing before publicizing it on the web. They made the wrong character set optional. They made [0-9] option in the fourth sub-option of option 2 (group 9). This allows the regex to match incorrectly formatted postcodes like AAA 1AA .

To fix this issue, make the next character class optional instead (and subsequently make the set [0-9] match exactly once):

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

Problem 5 – Performance

Performance on this regex is extremely poor. First off, they placed the least likely pattern option to match GIR 0AA at the beginning. How many users will likely have this postcode versus any other postcode; probably never? This means every time the regex is used, it must exhaust this option first before proceeding to the next option. To see how performance is impacted check the number of steps the original regex took (35) against the same regex after having flipped the options (22).

The second issue with performance is due to the way the entire regex is structured. There’s no point backtracking over each option if one fails. The way the current regex is structured can greatly be simplified. I provide a fix for this in the Answer section.

Problem 6 – Spaces

See regex in use here

This may not be considered a problem , per se, but it does raise concern for most developers. The spaces in the regex are not optional, which means the users inputting their postcodes must place a space in the postcode. This is an easy fix by simply adding ? after the spaces to render them optional. See the Answer section for a fix.


Risposta

1. Fixing the UK Government’s Regex

Fixing all the issues outlined in the Problems section and simplifying the pattern yields the following, shorter, more concise pattern. We can also remove most of the groups since we’re validating the postcode as a whole (not individual parts):

See regex in use here

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

This can further be shortened by removing all of the ranges from one of the cases (upper or lower case) and using a case-insensitive flag. Note : Some languages don’t have one, so use the longer one above. Each language implements the case-insensitivity flag differently.

See regex in use here .

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

Shorter again replacing [0-9] with \d (if your regex engine supports it):

See regex in use here .

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

2. Simplified Patterns

Without ensuring specific alphabetic characters, the following can be used (keep in mind the simplifications from 1. Fixing the UK Government’s Regex have also been applied here):

See regex in use here .

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

And even further if you don’t care about the special case GIR 0AA :

 ^[AZ]{1,2}\d[AZ\d]? ?\d[AZ]{2}$ 

3. Complicated Patterns

I would not suggest over-verification of a postcode as new Areas, Districts and Sub-districts may appear at any point in time. What I will suggest potentially doing, is added support for edge-cases. Some special cases exist and are outlined in this Wikipedia article .

Here are complex regexes that include the subsections of 3.

In relation to the patterns in 1. Fixing the UK Government’s Regex :

See regex in use here

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

And in relation to 2. Simplified Patterns :

See regex in use here

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

3.1 British Overseas Territories

The Wikipedia article currently states (some formats slightly simplified):

  • AI-1111 : Anguila
  • ASCN 1ZZ : Ascension Island
  • STHL 1ZZ : Saint Helena
  • TDCU 1ZZ : Tristan da Cunha
  • BBND 1ZZ : British Indian Ocean Territory
  • BIQQ 1ZZ : British Antarctic Territory
  • FIQQ 1ZZ : Falkland Islands
  • GX11 1ZZ : Gibraltar
  • PCRN 1ZZ : Pitcairn Islands
  • SIQQ 1ZZ : South Georgia and the South Sandwich Islands
  • TKCA 1ZZ : Turks and Caicos Islands
  • BFPO 11 : Akrotiri and Dhekelia
  • ZZ 11 & GE CX : Bermuda (according to this document )
  • KY1-1111 : Cayman Islands (according to this document )
  • VG1111 : British Virgin Islands (according to this document )
  • MSR 1111 : Montserrat (according to this document )

An all-encompassing regex to match only the British Overseas Territories might look like this:

See regex in use here .

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

3.2 British Forces Post Office

Although they’ve been recently changed it to better align with the British postcode system to BF# (where # represents a number), they’re considered optional alternative postcodes . These postcodes follow(ed) the format of BFPO , followed by 1-4 digits:

See regex in use here

 ^BFPO ?\d{1,4}$ 

3.3 Santa?

There’s another special case with Santa (as mentioned in other answers): SAN TA1 is a valid postcode. A regex for this is very simply:

 ^SAN ?TA1$ 

I needed a version that would work in SAS with the PRXMATCH and related functions, so I came up with this:

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

Test cases and 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;