Почтовые индексы могут быть изменены, и единственный верный способ проверить почтовый индекс - это иметь полный список почтовых индексов и посмотреть, есть ли он там.
Но регулярные выражения полезны, потому что они:
- просты в использовании и реализации
- короткие
- быстро запустить
- довольно прост в обслуживании (по сравнению с полным списком почтовых индексов)
- по-прежнему перехватывает большинство ошибок ввода
Но регулярные выражения, как правило, трудно поддерживать, особенно для тех, кто их не придумал. Так должно быть:
- настолько легко понять, насколько это возможно
- относительно будущее
Это означает, что большинство регулярных выражений в этом ответе недостаточно хороши. Например. Я вижу, что [A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRV-Y]
будет соответствовать области почтового индекса в форме AA1A - но это будет боль в шее, если и когда будет добавлена новая область почтового индекса, потому что трудно понять, какие области почтовых индексов она соответствует.
Я также хочу, чтобы мое регулярное выражение совпадало с первой и второй половиной почтового индекса в виде скобок.
Итак, я придумал это:
(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})
В формате PCRE его можно записать следующим образом:
/^
( 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
Для меня это правильный баланс между проверкой в максимально возможной степени, но в то же время перспективой и возможностью легкого обслуживания.