Pergunta

Eu sou depois de uma regex que irá validar um complexo código postal completo apenas no Reino Unido dentro de uma cadeia de entrada. Todas as formas de código postal incomuns devem ser cobertos, bem como a habitual. Por exemplo:

Jogos

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

Sem Jogo

  • aWC2H 7LT
  • WC2H 7LTa
  • WC2H

Como posso resolver este problema?

Foi útil?

Solução

Eu recomendo dar uma olhada no Governo do Reino Unido de dados padrão para códigos postais [link agora morto, Arquivo de XML, consulte Wikipedia para discussão]. Há uma breve descrição sobre os dados e o esquema XML anexado fornece uma expressão regular. Pode não ser exatamente o que você quiser, mas seria um bom ponto de partida. As difere RegEx do XML ligeiramente, como um personagem P na terceira posição em formato A9A 9AA é permitido pela definição dada.

O RegEx fornecido pelo Governo do Reino Unido foi:

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

Como foi salientado na discussão Wikipedia, isso vai permitir que alguns códigos postais não reais (por exemplo, os AA partida, ZY) e eles não fornecem um teste mais rigoroso que você poderia tentar.

Outras dicas

Parece que vamos estar usando ^(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})$, que é uma versão ligeiramente modificada do que sugerido por Minglis acima.

No entanto, nós vamos ter que investigar exatamente quais são as regras, como as várias soluções listados acima parecem aplicar regras diferentes a respeito de que são permitidas letras.

Depois de alguma pesquisa, nós encontramos mais algumas informações. Aparentemente, uma página em pontos 'govtalk.gov.uk'-o para uma especificação de código postal govtalk-postcodes . Isso aponta para um esquema XML em XML Schema que fornece um 'pseudo regex' declaração das regras de código postal.

Temos tido isso e trabalhou com ele um pouco para nos dar a seguinte expressão:

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

Isso faz com que espaços opcional, mas o limita a um espaço (substituir o 'e' com '{0,} para espaços ilimitadas). Ele assume todo o texto deve ser superior a caso.

Se você quiser permitir minúsculas, com qualquer número de espaços, use:

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

Esta não cobre territórios ultramarinos e só reforça o formato, não a existência de diferentes áreas. É com base nas seguintes regras:

Pode aceitar os seguintes formatos:

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

Onde:

  • 9 pode ser qualquer número único dígito.
  • A pode ser qualquer letra exceto Q, V ou X.
  • B pode ser qualquer letra exceto I, J ou Z.
  • C pode ser qualquer carta excepto para I, L, M, N, O, P, Q, R, V, X, Y ou Z.
  • D pode ser qualquer carta excepto para I, J ou Z.
  • E pode ser qualquer um de A, B, E, H, M, N, P, R, V, W, X ou Y.
  • Z pode ser qualquer carta excepto para C, I, K, M, O ou V.

Os melhores cumprimentos

Colin

Não existe tal coisa como um Reino Unido Código Postal expressão regular abrangente que é capaz de validação um código postal. Você pode verificar se um código postal está no formato correto usando uma expressão regular; não que ele realmente existe.

Postcodes são arbitrariamente complexo e em constante mudança. Por exemplo, o W1 outcode não faz, e nunca poderá, tem todo o número entre 1 e 99, para cada área de código postal.

Você não pode esperar o que está lá atualmente para ser verdade para sempre. Como exemplo, em 1990, os Correios decidiram que Aberdeen estava ficando um pouco lotado. Eles adicionado um 0 com o fim de AB1-5 tornando-AB10-50 e em seguida criada uma série de códigos postais de entre estes.

Sempre que uma nova rua é construir um novo código postal é criada. É parte do processo para a obtenção de licenças de construção; autoridades locais são obrigados a manter este atualizado com o Post Office (não que todos eles fazem).

Além disso, como observado por um número de outros usuários, há os códigos postais especiais, tais como Girobank, GIR 0AA, ea outra para cartas ao Papai, SAN TA1 - você provavelmente não quer alguma coisa post, mas ele doesn' t parecem estar cobertos por qualquer outra resposta.

Então, há os códigos postais BFPO, que agora estão mudança para formato mais padrão. Ambos os formatos vão ser válido. Por fim, há os territórios ultramarinos fonte Wikipedia .

+----------+----------------------------------------------+
| Postcode |                   Location                   |
+----------+----------------------------------------------+
| AI-2640  | Anguilla                                     |
| 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 1AA | Gibraltar                                    |
| PCRN 1ZZ | Pitcairn Islands                             |
| SIQQ 1ZZ | South Georgia and the South Sandwich Islands |
| TKCA 1ZZ | Turks and Caicos Islands                     |
+----------+----------------------------------------------+

Em seguida, você tem que ter em conta que o Reino Unido "exportado" seu sistema de código postal para muitos lugares do mundo. Tudo o que valida um código postal "UK" também irá validar os códigos postais de uma série de outros países.

Se você quiser validate a UK código postal a forma mais segura de fazer isso é usar um look-up de códigos postais atuais. Há uma série de opções:

  • lançamentos Ordnance Survey Código-Point Abrir sob uma licença de dados aberto. Vai ser muito ligeiramente para trás os tempos, mas é gratuito. Este será (provavelmente - não me lembro) não incluem dados da Irlanda do Norte como o Ordnance Survey não tem competência lá. Mapeamento na Irlanda do Norte é realizado pelo Ordnance Survey da Irlanda do Norte e eles têm o seu, separado, paga-para, produto Pointer . Você poderia usar isso e anexar os poucos que não são cobertos com bastante facilidade.

  • Royal Mail libera o Código Postal Endereço Arquivo (PAF) , isso inclui BFPO que eu sou não tenho certeza Código-Point Abra o faz. Ele é atualizado regularmente, mas custa dinheiro (e que pode ser francamente média sobre isso algumas vezes). PAF inclui o endereço completo em vez de apenas os códigos postais e vem com seu próprio Programadores Guia . Os dados do usuário Open Group (ODUG) está fazendo lobby para ter PAF liberado de graça, aqui está uma descrição de sua posição .

  • Por fim, há AddressBase . Esta é uma colaboração entre o levantamento topográfico, as autoridades locais, Royal Mail e uma empresa de harmonização para criar um diretório definitivo de todas as informações sobre todos os endereços do Reino Unido (eles têm sido bastante sucesso também). É pago para, mas se você está trabalhando com uma autoridade local, departamento governamental ou serviço público é gratuito para que eles utilizam. Thermuito mais informações do que e códigos postais apenas incluídos.

Eu recentemente postou uma resposta para esta pergunta em códigos postais do Reino Unido para o linguagem R. Eu descobri que padrão regex do Governo do Reino Unido está incorreta e não corretamente validar algumas códigos postais. Infelizmente, muitas das respostas aqui são baseados neste padrão incorreto.

Eu vou delinear algumas dessas questões abaixo e fornecer uma expressão regular revisado que realmente obras.


Nota

Minha resposta (e expressões regulares em geral):

  • só valida código postal formatos .
  • não garante que um código postal legitimamente existe .
    • Para isso, use uma API apropriado! Consulte de Ben resposta para mais informações.

Se você não se preocupam com o mau regex e só quero pular para a resposta, desloque-se para o Resposta .

A Bad Regex

As expressões regulares nesta seção não deve ser utilizado.

Este é o regex não que o governo do Reino Unido forneceu desenvolvedores (não tenho certeza quanto tempo esta ligação vai ser para cima, mas você pode vê-lo em sua Bulk Data documentação de transferência ):

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

Problemas

Problema 1 - copiar / colar

Veja regex em uso aqui .

Como muitos desenvolvedores provavelmente fazer, eles copiar / colar o código (expressões regulares, especialmente) e colá-los esperando-los para o trabalho. Enquanto isso é ótimo na teoria, ele falha, neste caso particular, porque copiar / colar a partir deste documento realmente muda um dos caracteres (um espaço) em um caractere de nova linha como mostrado abaixo:

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

A primeira coisa que a maioria dos desenvolvedores vai fazer é apenas apagar a nova linha sem pensar duas vezes. Agora o regex não vai coincidir com códigos postais com espaços entre eles (exceto o código postal GIR 0AA).

Para corrigir esse problema, o caractere de nova linha deve ser substituído com o caractere de espaço:

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

Problema 2 - Limites

Veja regex em uso aqui .

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

O regex código postal ancora indevidamente a regex. Qualquer pessoa que utilize este regex para validar códigos postais pode ser surpreendido se um valor como fooA11 1AA fica completamente. Isso porque eles já ancorado no início da primeira opção e o fim da segunda opção (independentemente um do outro), como fora pontas no regex acima.

O que isto significa é que ^ (assevera posição no início da linha) só funciona no primeiro ([Gg][Ii][Rr] 0[Aa]{2}) opção, então a segunda opção irá validar quaisquer cordas que final em um código postal (independentemente do que vem antes).

Da mesma forma, a primeira opção não é ancorada ao final do $ linha, então GIR 0AAfoo também é aceita.

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

Para corrigir esse problema, ambas as opções devem ser embrulhados em outro grupo (ou grupo de não captura) e as âncoras colocados ao redor que:

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

Problema 3 - Conjunto de Caracteres inadequada

Veja regex em uso aqui .

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

O regex está faltando um - aqui para indicar um intervalo de caracteres. Tal como está, se um código postal é na ANA NAA formato (onde A representa uma letra e N representa um number), e começa com outra coisa senão A ou Z, ele irá falhar.

Isso significa que ele irá corresponder A1A 1AA e Z1A 1AA, mas não B1A 1AA.

Para corrigir esse problema, o - personagem deve ser colocado entre o A e Z no respectivo conjunto de caracteres:

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

Problema 4 - Errado conjunto de caracteres Opcional

Veja regex em uso aqui .

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

Eu juro que eles nem sequer testar esta coisa antes de divulgá-la na web. Eles fizeram o errado conjunto de caracteres opcional. Fizeram opção [0-9] no quarto sub-opção de opção 2 (grupo 9). Isso permite que o regex para coincidir com códigos postais formatados incorretamente como AAA 1AA.

Para corrigir esse problema, fazer a classe de personagem próxima opcionais em vez (e, posteriormente, fazer o jogo conjunto [0-9] exatamente uma vez):

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

Problema 5 - Desempenho

Performance neste regex é extremamente pobre. Primeiro, eles colocaram a opção menos provável padrão para corresponder GIR 0AA no início. Como muitos usuários provavelmente terá este código postal contra qualquer outro código postal; provavelmente nunca? Isso significa que cada vez que a regex é usado, ele deve esgotar esta opção antes de continuar para a próxima opção. Para ver como o desempenho é afetado verificar o número de passos a regex originais levou (35) contra o < a href = "https://regex101.com/r/ajQHrd/6" rel = "noreferrer"> mesmo regex depois de ter virado as opções (22).

O segundo problema com o desempenho é devido à forma como toda a regex é estruturado. Não há nenhum ponto retrocesso sobre cada opção se um falhar. A forma como o regex atual está estruturado pode extremamente ser simplificada. Eu fornecer uma correção para isso no Resposta .

Problema 6 - Espaços

Veja regex em uso aqui

Isto não pode ser considerado um problema , per se, mas ele faz preocupação aumento para a maioria dos desenvolvedores. Os espaços no regex não são opcionais, o que significa que os usuários inserindo seus códigos postais deve colocar um espaço no código postal. Este é um reparo fácil simplesmente adicionando ? após os espaços para torná-los opcionais. Veja Resposta seção para uma correção.


Resposta

1. Fixação Regex do Governo do Reino Unido

Corrigir todos os problemas descritos no Problema seção e simplificando o padrão produz o seguinte, mais curto mais padrão, concisa. Nós também pode remover a maioria dos grupos, já que estamos validando o código postal como um todo (e não partes individuais):

Veja regex em uso aqui

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

Isto pode ainda ser encurtado por remoção de todos os intervalos de um dos casos (caso superior ou inferior) e, usando um sinal de maiúsculas e minúsculas. Nota : Algumas línguas não tiver um, então use o mais acima. Cada implementos língua a bandeira caso insensibilidade diferente.

Veja regex em uso aqui .

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

Shorter [0-9] novamente substituindo com \d (se o seu motor regex suporta):

Veja regex em uso aqui .

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

2. Padrões simplificados

Sem garantia de caracteres alfabéticos específicos, o seguinte pode ser usado (Tenha em mente as simplificações de 1 Fixação Regex do Governo do Reino Unido também foram aplicadas aqui.):

Veja regex emusar aqui .

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

E ainda mais se você não se preocupam com o caso GIR 0AA especial:

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

3. Padrões complicados

Eu não sugeriria excesso de verificação de um código postal como novas áreas, distritos e sub-distritos podem aparecer em qualquer ponto no tempo. O que vou sugerir apoio potencialmente fazendo, é adicionado para Edge-casos. Existem alguns casos especiais e estão descritos no esta Wikipedia artigo .

Aqui são expressões regulares complexos que incluem as subsecções de 3. (3.1, 3.2, 3.3).

Em relação aos padrões em 1. Fixação Regex do Governo do Reino Unido :

Veja regex em uso aqui

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

E em relação ao 2. Padrões simplificados :

Veja regex em uso aqui

^(([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 territórios ultramarinos britânicos

O artigo da Wikipedia afirma atualmente (alguns formatos ligeiramente simplificada):

  • AI-1111: Anguila
  • ASCN 1ZZ: Ilha de Ascensão
  • STHL 1ZZ: Santa Helena
  • TDCU 1ZZ: Tristan da Cunha
  • BBND 1ZZ: British Indian Ocean Territory
  • BIQQ 1ZZ Britânica Antarctic Territory
  • FIQQ 1ZZ: Ilhas Falkland
  • GX11 1ZZ: Gibraltar
  • PCRN 1ZZ: Ilhas Pitcairn
  • SIQQ 1ZZ: Geórgia do Sul e Sandwich do Sul
  • TKCA 1ZZ: Ilhas Turks e Caicos
  • BFPO 11: Akrotiri e Dhekelia
  • ZZ 11 & GE CX: Bermuda (de acordo com este documento )
  • KY1-1111: Ilhas Cayman (de acordo com este documento)
  • VG1111: British Virgin Islands (de acordo com este documento )
  • MSR 1111: Montserrat (de acordo com a este documento )

Um abrangente regex para corresponder apenas os territórios ultramarinos britânicos pode ter esta aparência:

Veja regex em uso aqui .

^((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 britânico Forças Post Office

Apesar de terem sido recentemente mudou para melhor alinhar com o sistema de código postal britânico para BF# (onde # representa um número), eles são considerados postcodes alternativas opcionais . Estes códigos postais seguir (ed) o formato de BFPO, seguido de 1-4 dígitos:

Veja regex em uso aqui

^BFPO ?\d{1,4}$

3.3 de Santa?

Há um outro caso especial com o Papai (como mencionado em outras respostas): SAN TA1 é um código postal válido. A regex para isso é muito simples:

^SAN ?TA1$

Eu tinha um olhar em algumas das respostas acima e eu recomendo contra o uso do padrão de @ de Dan resposta (c. 15 de dezembro '10) , uma vez incorretamente bandeiras quase 0,4% dos códigos postais válidos como inválida, enquanto os outros não.

Ordnance Survey fornecer serviço chamado Ponto de Código Aberto, que:

contém uma lista de todas as unidades de código postal atuais na Grã-Bretanha

Eu corri cada um dos regexs acima contra a lista completa dos códigos postais (6 Jul '13) a partir desta dados usando 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"

Existem 1,686,202 postcodes total.

A seguir estão os números de códigos postais válidos que fazer não combinar cada $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

É claro que esses resultados só lidar com os códigos postais válidos que são sinalizados incorretamente como inválido. Assim:

'^.*$'
# => 0

Eu estou dizendo nada sobre qual padrão é a melhor sobre filtragem de códigos postais inválidos.

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

expressão regular para corresponder válida Reino Unido códigos postais. No sistema postal do Reino Unido não todas as letras são usadas em todas as posições (O mesmo com matrícula do veículo placas) e existem várias regras para governam este. Este regex leva em conta essas regras. Detalhes da regras: Primeiro semestre de código postal válido formatos [A-Z] [A-Z] [0-9] [A-Z] [A-Z] [A-Z] [0-9] [0-9] [A-Z] [0-9] [0-9] [A-Z] [A-Z] [0-9] [A-Z] [A-Z] [A-Z] [A-Z] [0-9] [A-Z] [A-Z] [0-9] Excepções Posição - First. Contraint - QVX não Posição usado - Segunda. contraint - IJZ não utilizado, exceto em GIR 0AA Posição - Terceiro. Limitação - AEHMNPRTVXY usado apenas Position - Adiante. Contraint - ABEHMNPRVWXY segundo lugar metade do código postal formatos válidos [0-9] [A-Z] [A-Z] Exceções Position - Segunda e Terceira. Contraint - CIKMOV Não usado

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

A maioria das respostas aqui não funcionou para todos os códigos postais que tenho no meu banco de dados. Eu finalmente encontrei um que valida com tudo, usando o novo regex fornecido pelo governo:

https: // www .gov.uk / governo / uploads / system / uploads / attachment_data / arquivo / 413338 / Bulk_Data_Transfer _-_ additional_validation_valid_from_March_2015.pdf

Não é em qualquer uma das respostas anteriores para que eu postá-lo aqui para o caso de ter o link abaixo:

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

UPDATE: Atualizado regex como apontado por Jamie Touro. Não tenho certeza se era a minha cópia de erro ou era um erro no regex do governo, o link está em baixo agora ...

UPDATE: Como ctwheels encontrado, esta regex funciona com o sabor javascript regex. Veja o seu comentário a uma que funciona com o sabor pcre (php).

De acordo com esta tabela Wikipedia

enter descrição da imagem aqui

Esta cobertura padrão de todos os casos

(?:[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 usá-lo sobre o uso de Android \ Java \\ d

Um post antigo, mas ainda bastante elevado nos resultados do Google então pensei que atualizar. Este 14 de outubro doc define a expressão regular UK código postal como:

^([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 / governo / uploads / system / uploads / attachment_data / arquivo / 359448 / 4__Bulk_Data_Transfer _-_ additional_validation_valid.pdf

O documento também explica a lógica por trás dele. No entanto, tem um erro (em negrito) e também permite minúsculas, que, embora legal não é usual versão, assim alterado:

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

Isso funciona com novos códigos postais de Londres (por exemplo W1D 5LH) que as versões anteriores não.

Esta é a regex Google serve em seu domínio 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}

Postcodes estão sujeitos a mudança, e a única verdadeira forma de validar um código postal é ter a lista completa dos códigos postais e ver se ele está lá.

Mas as expressões regulares são úteis porque:

  • são fáceis de usar e implementar
  • são curtos
  • são rápidos para executar
  • são muito fáceis de manter (em comparação com uma lista completa dos códigos postais)
  • ainda pegar a maioria dos erros de entrada

Mas expressões regulares tendem a ser difíceis de manter, especialmente para alguém que não veio com ele em primeiro lugar. Assim deve ser:

  • tão fácil de entender quanto possível
  • relativamente à prova do futuro

Isso significa que a maioria das expressões regulares em esta resposta não são bons o suficiente. Por exemplo. Eu posso ver que [A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRV-Y] vai coincidir com uma área de código postal do AA1A forma - mas vai ser uma dor no pescoço, se e quando uma nova área de código postal é adicionado, porque é difícil de entender quais as áreas de código postal que corresponda

Eu também quero a minha expressão regular para coincidir com a primeira e segunda metade do código postal como partidas parenthesised.

Então, eu vim com isso:

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

formato Em PCRE pode ser escrito da seguinte forma:

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

Para mim, este é o equilíbrio certo entre a validação, tanto quanto possível, enquanto ao mesmo tempo futuro à prova e permitindo a fácil manutenção.

Eu estive procurando um regex código postal do Reino Unido para o último dia ou assim e tropeçou em esta discussão. Eu trabalhei minha maneira com a maioria das sugestões acima e nenhum deles funcionou para mim, então eu vim com a minha própria regex que, tanto quanto eu sei, captura todos os códigos postais do Reino Unido válida a partir de Jan '13 (de acordo com a literatura mais recente de o Royal mail).

O regex e alguns código postal simples verificação de código PHP é afixado abaixo. NOTA: - Permite postcodes minúsculas ou maiúsculas e da GIR 0AA anomalia, mas para lidar com a, mais do que provável, a presença de um espaço no meio de um código postal entrou também faz uso de um str_replace simples para remover o espaço antes do teste contra a regex. Qualquer discrepância além disso e do Royal Mail si nem sequer mencioná-los em sua literatura (ver http://www.royalmail.com/sites/default/files/docs/pdf/programmers_guide_edition_7_v5.pdf e começar a ler a partir da página 17)!

Nota: Na própria literatura do Royal Mail (link acima) há uma ligeira ambiguidade que rodeia as 3ª e 4ª posições e as exceções no lugar, se esses personagens são letras. I contatado diretamente Royal Mail para esclarecê-lo e em suas próprias palavras "Uma carta na posição 4 do Outward Código com o formato AANA NAA não tem exceções e as 3ª exceções posição aplicam-se apenas à última letra da Outward Código com o formatar ANA ANA ". Diretamente da boca do cavalo!

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

    }

?>

Espero que ajude qualquer outra pessoa que se depara com esta discussão em busca de uma solução.

Aqui está uma regex baseado no formato especificado nos documentos que estão ligados a resposta de marcj:

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

A única diferença entre isso e as especificações é que os últimos 2 caracteres não podem ser apresentados em [CIKMOV] de acordo com as especificações.

Edit: Aqui está outra versão que faz teste para as limitações de caracteres à direita.

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

Alguns dos regexs acima são um pouco restritivo. Observe o código postal genuína:. "W1K 7AA" seria um fracasso, dada a regra de "Posição 3 - AEHMNPRTVXY usado apenas" acima como "K" seria anulado

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

Parece um pouco mais preciso, consulte o href="http://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom" rel="nofollow"> artigo .

Note que este regex exige maiúscula somente caracteres.

A grande questão é saber se você está restringindo a entrada do usuário para permitir que apenas os códigos postais que realmente existem ou se você está simplesmente tentando impedir que os usuários de entrar besteira completa para os campos do formulário. Correspondendo corretamente cada código postal possível, e os ensaios futuros, é um quebra-cabeça mais difícil, e provavelmente não vale a pena a menos que esteja HMRC.

Eu uso o seguinte regex que eu tenha testado contra todos os códigos postais do Reino Unido válido. É com base nas regras recomendadas, mas condensado tanto quanto razoável e não faz uso de quaisquer regras específicas regex linguagem especial.

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

Assume-se que o código postal tem sido convertido para maiúsculas e não tem esquerda ou à direita caracteres, mas irá aceitar um espaço opcional entre o outcode e inCode.

O especial "GIR0 0AA" código postal é excluído e não validará como não é na lista oficial de Correios dos códigos postais e, tanto quanto eu saiba não será usado como endereço registrado. Acrescentando que deveria ser trivial como um caso especial, se necessário.

Primeiro semestre de código postal formatos válidos

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

Exceções
Posição 1 - QVX não utilizado
Posição 2 - IJZ não utilizado, exceto em GIR 0AA
Posição 3 - AEHMNPRTVXY usado apenas
Posição 4 - ABEHMNPRVWXY

Segunda metade do código postal

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

Exceções
Posição 2 + 3 - CIKMOV não utilizados

Lembre-se nem todos os códigos possíveis são utilizados, então esta lista é uma condição necessária, mas não sufficent para um código válido. Pode ser mais fácil apenas para o jogo contra uma lista de todos os códigos válidos?

é aqui como temos lidado com a questão código postal UK:

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

Explicação:

  • esperar 1 ou 2 caracteres A-Z, superior ou inferior fina
  • esperar 1 ou 2 números
  • esperar 0 ou 1 a-z char, superior ou inferior fina
  • espaço opcional permitido
  • esperar um número
  • esperar 2 a-z, superior ou inferior fina

Este recebe a maioria dos formatos, que, em seguida, usar o db para validar se o código postal é realmente real, esses dados é impulsionado por openpoint https://www.ordnancesurvey.co.uk/opendatadownload/products.html

espero que isso ajude

Para verificar um código postal está em um formato válido de acordo com o Royal Mail guia do programador :

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

Todos os códigos postais no doogal.co.uk jogo, exceto para aqueles que não estão mais em uso.

Adicionando um ? após o espaço e usando jogo de maiúsculas e minúsculas para responder a esta pergunta:

'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" ]

Este permite espaços e as abas vazias de ambos os lados no caso de você não quer falhar validação e, em seguida, prepará-la Sever lado.

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

Eu queria uma regex simples, onde não há problema em permitir que muito, mas não negar um código postal válido. Eu fui com este (a entrada é um / string aparado despojado):

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

Comprimentos 5-7 (sem contar os espaços em branco) significa que permitir que os mais curtos possíveis códigos postais como "L1 8JQ", bem como os mais longos como "OL14 5ET".

EDIT:. Mudou a 8 para a 7 portanto, não permitem 8 postcodes caráter

Para adicionar a esta lista um regex mais prática que eu uso que permite que o usuário digite um 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}))$

Este regex permite letras maiúsculas e minúsculas com um espaço opcional entre

A partir de uma desenvolvedores de software ponto de vista este regex é útil para software onde um endereço pode ser opcional. Por exemplo, se um usuário não quiser fornecer seus detalhes de endereço

Tenha uma olhada no código python desta página:

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

Eu tenho algum código postal analisar a fazer. A exigência é muito simples; Eu tenho que analisar um código postal em um outcode e (opcional) inCode. A boa nova é que eu não tenho para executar qualquer validação - Eu só tenho que picar o que eu tenho fornecido com de uma forma vagamente inteligente. Eu não posso assumir muito sobre a minha importação em termos de formatação, ou seja, caso e espaços incorporados. Mas esta não é a má notícia; a má notícia é que eu tenho que fazer tudo isso em RPG. : - (

No entanto, eu joguei um pouco de função Python em conjunto para esclarecer o meu pensamento.

Eu usei-o para códigos postais processo para mim.

Nos foi dado um spec:

UK postcodes must be in one of the following forms (with one exception, see below): 
    § A9 9AA 
    § A99 9AA
    § AA9 9AA
    § AA99 9AA
    § A9A 9AA
    § AA9A 9AA
where A represents an alphabetic character and 9 represents a numeric character.
Additional rules apply to alphabetic characters, as follows:
    § The character in position 1 may not be Q, V or X
    § The character in position 2 may not be I, J or Z
    § The character in position 3 may not be I, L, M, N, O, P, Q, R, V, X, Y or Z
    § The character in position 4 may not be C, D, F, G, I, J, K, L, O, Q, S, T, U or 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.

Nós viemos com esta:

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

Mas nota - isto permite que qualquer número de espaços entre os grupos.

Eu tenho o regex para validação Reino Unido Código Postal.

Este está a trabalhar por todos os tipos de Código Postal quer interna ou externa

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

Esse é um trabalho para todos os tipos de formato.

Exemplo:

AB10 --------------------> SOMENTE POSTCODE EXTERIOR

A1 1AA ------------------> combinação de (exterior e interior) CÓDIGO POSTAL

WC2A --------------------> EXTERIOR

A resposta aceita reflecte as regras dadas pelo Royal Mail, embora haja um erro de digitação na regex. Este erro de digitação parece ter sido lá no site gov.uk bem (como é na página de arquivo XML).

No formato A9A 9AA as regras permitem que um personagem P na terceira posição, enquanto a regex não permite isso. A regex correto seria:

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

Encurtar Isto resulta na seguinte regex (que usa a sintaxe 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})

Ele também inclui um espaço opcional entre o primeiro eo segundo bloco.

O que tenho encontrado em quase todas as variações e o regex do pdf de transferência em massa eo que está no site wikipedia é este, especificamente para o regex wikipedia é, é preciso haver um ^ após o primeiro | (barra vertical) . Eu descobri isso por meio de testes para AA9A 9AA, porque caso contrário a verificação de formato para A9A 9AA irá validá-lo. Por exemplo verificação de EC1D 1BB que deve ser inválida volta válido porque C1D 1BB é um formato válido.

Aqui está o que eu vim acima com um bom 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})$

Eu precisava de uma versão que iria trabalhar em SAS com o PRXMATCH e funções relacionadas, então eu vim com essa:

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

Os casos de teste e notas:

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

Abaixo método irá verificar o código postal e fornecer informações completas

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

Eu roubei este de um documento XML e parece para cobrir todos os casos sem o GIRO codificado duro:

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

(sintaxe de Ruby com ignorar caso)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top