Почтовый индекс Великобритании (полное)

Мне нужно регулярное выражение, которое будет проверять полный комплексный почтовый индекс Великобритании только во входной строке. Все необычные формы почтовых индексов должны быть покрыты так же, как и обычные. Например:

Матчи

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

Не совпадает

  • AWC2H 7LT
  • WC2H 7LTa
  • WC2H

Существуют ли официальные или даже полуофициальные регулярные выражения для такого рода вещей? Любой другой совет относительно форматирования и хранения их в базе данных?

34 ответа

Решение

Я бы рекомендовал взглянуть на стандарт данных правительства Великобритании для почтовых индексов [ссылка сейчас не работает; архив XML, см. Википедию для обсуждения. Существует краткое описание данных, а присоединенная XML-схема содержит регулярное выражение. Это может быть не совсем то, что вы хотите, но будет хорошей отправной точкой. RegEx немного отличается от XML, так как символ P в третьей позиции в формате A9A 9AA допускается данным определением.

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

Как указывалось в обсуждении в Википедии, это позволит использовать некоторые нереальные почтовые индексы (например, те, которые начинаются с AA, ZY), и они предоставляют более строгий тест, который вы можете попробовать.

Я недавно опубликовал ответ на этот вопрос в британских почтовых индексах для языка R. Я обнаружил, что шаблон регулярных выражений правительства Великобритании неверен и не может правильно проверить некоторые почтовые индексы. К сожалению, многие ответы здесь основаны на этой неправильной схеме.

Я изложу некоторые из этих вопросов ниже и предоставлю исправленное регулярное выражение, которое действительно работает.


Заметка

Мой ответ (и регулярные выражения в целом):

  • Проверяет только форматы почтовых индексов.
  • Не гарантирует, что почтовый индекс законно существует.
    • Для этого используйте соответствующий API! Смотрите ответ Бена для получения дополнительной информации.

Если вас не интересует плохое регулярное выражение, и вы просто хотите перейти к ответу, прокрутите вниз до раздела " Ответ ".

Плохое регулярное выражение

Регулярные выражения в этом разделе не должны использоваться.

Это ошибочное регулярное выражение, которое правительство Великобритании предоставило разработчикам (не уверен, как долго будет работать эта ссылка, но вы можете увидеть это в их документации Bulk Data Transfer):

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

Проблемы

Проблема 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})$

Первое, что сделает большинство разработчиков, это просто удалите новую строку, не задумываясь. Теперь регулярное выражение не будет сопоставлять почтовые индексы с пробелами в них (кроме GIR 0AA почтовый индекс).

Чтобы решить эту проблему, символ новой строки должен быть заменен символом пробела:

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

Проблема 2 - Границы

Смотрите регулярное выражение в использовании здесь.

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

Регулярное выражение почтового индекса неправильно привязывает регулярное выражение. Любой, кто использует это регулярное выражение для проверки почтовых индексов, может быть удивлен, если такое значение как fooA11 1AA проходит через Это потому, что они привязали начало первого и конец второго (независимо друг от друга), как указано в регулярном выражении выше.

Это значит, что ^ (утверждает позицию в начале строки) работает только на первом варианте ([Gg][Ii][Rr] 0[Aa]{2})Таким образом, вторая опция будет проверять любые строки, заканчивающиеся почтовым индексом (независимо от того, что будет раньше).

Точно так же первый вариант не привязан к концу строки $, так GIR 0AAfoo также принято.

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

Чтобы решить эту проблему, оба параметра должны быть заключены в другую группу (или группу без захвата), а вокруг них должны быть размещены якоря:

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

Проблема 3 - Неправильный набор символов

Смотрите регулярное выражение в использовании здесь.

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

Регулярное выражение отсутствует - здесь, чтобы указать диапазон символов. Как оно есть, если почтовый индекс в формате ANA NAA (где A представляет письмо и N представляет собой число), и оно начинается с чего-либо, кроме A или же Z, это не удастся.

Это означает, что это будет соответствовать A1A 1AA а также Z1A 1AA, но нет B1A 1AA,

Чтобы исправить эту проблему, персонаж - должен быть помещен между A а также Z в соответствующем наборе символов:

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

Проблема 4 - Неправильный дополнительный набор символов

Смотрите регулярное выражение в использовании здесь.

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

Клянусь, они даже не тестировали эту вещь, прежде чем публиковать ее в Интернете. Они сделали неправильный набор символов необязательным. Они сделали [0-9] вариант в четвертом подопции варианта 2 (группа 9). Это позволяет регулярному выражению соответствовать неправильно отформатированным почтовым индексам, таким как AAA 1AA,

Чтобы решить эту проблему, сделайте следующий класс символов необязательным (и впоследствии сделайте набор [0-9] совпадать ровно один раз):

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

Проблема 5 - Производительность

Производительность на этом регулярном выражении крайне плохая. Во-первых, они поместили наименее вероятный вариант шаблона для соответствия GIR 0AA в начале. Сколько пользователей будет иметь этот почтовый индекс по сравнению с любым другим почтовым индексом; наверное никогда? Это означает, что каждый раз, когда используется регулярное выражение, он должен сначала исчерпать эту опцию, прежде чем перейти к следующей. Чтобы увидеть, как это влияет на производительность, проверьте количество шагов, которые исходное регулярное выражение (35) предприняло по отношению к тому же регулярному выражению после переключения опций (22).

Вторая проблема с производительностью связана с тем, как структурировано все регулярное выражение. Там нет смысла возвращаться к каждому варианту, если один не удастся. Способ структурирования текущего регулярного выражения может быть значительно упрощен. Я предоставлю исправление для этого в разделе Ответ.

Задача 6 - Пространства

Смотрите регулярное выражение в использовании здесь

Это само по себе не может считаться проблемой, но вызывает беспокойство у большинства разработчиков. Пробелы в регулярном выражении не являются обязательными, это означает, что пользователи, вводящие свои почтовые индексы, должны поместить пробел в почтовый индекс. Это легко исправить, просто добавив ? после пробелов отображать их необязательно. Смотрите раздел Ответ для исправления.


Ответ

1. Исправление регулярного выражения правительства Великобритании

Исправление всех проблем, описанных в разделе " Проблемы ", и упрощение шаблона приводит к следующему, более короткому и краткому шаблону. Мы также можем удалить большинство групп, так как мы проверяем почтовый индекс в целом (не отдельные части):

Смотрите регулярное выражение в использовании здесь

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

Это может быть дополнительно сокращено путем удаления всех диапазонов из одного из регистров (верхнего или нижнего регистра) и использования флага без учета регистра. Примечание. Некоторые языки не имеют такового, поэтому используйте более длинный выше. Каждый язык реализует флаг нечувствительности к регистру по-своему.

Смотрите регулярное выражение в использовании здесь.

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

Короче опять замена [0-9] с \d (если ваш движок регулярных выражений поддерживает это):

Смотрите регулярное выражение в использовании здесь.

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

2. Упрощенные шаблоны

Без указания конкретных буквенных символов можно использовать следующее (имейте в виду, что здесь приведены упрощения из пункта 1. Исправление регулярного выражения правительства Великобритании):

Смотрите регулярное выражение в использовании здесь.

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

И даже дальше, если вас не волнует особый случай GIR 0AA:

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

3. Сложные паттерны

Я не предложил бы чрезмерную проверку почтового индекса, поскольку новые районы, районы и районы могут появиться в любой момент времени. Что я буду предлагать делать потенциально, так это добавленную поддержку для крайних случаев. Существуют некоторые особые случаи, которые описаны в этой статье Википедии.

Вот сложные регулярные выражения, которые включают в себя подразделы 3. (3.1, 3.2, 3.3).

По отношению к шаблонам в 1. Исправление регулярного выражения правительства Великобритании:

Смотрите регулярное выражение в использовании здесь

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

А по отношению к 2. Упрощенные паттерны:

Смотрите регулярное выражение в использовании здесь

^(([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 Британские заморские территории

Статья в Википедии в настоящее время утверждает (некоторые форматы немного упрощены):

  • AI-1111: Ангилья
  • ASCN 1ZZ: Остров Вознесения
  • STHL 1ZZ: Святой Елены
  • TDCU 1ZZТристан-да-Кунья
  • BBND 1ZZ: Британская территория Индийского океана
  • BIQQ 1ZZ: Британская Антарктическая Территория
  • FIQQ 1ZZ: Фолклендские острова
  • GX11 1ZZ: Гибралтар
  • PCRN 1ZZ: Острова Питкэрн
  • SIQQ 1ZZЮжная Георгия и Южные Сандвичевы острова
  • TKCA 1ZZ: Острова Теркс и Кайкос
  • BFPO 11: Акротири и Декелия
  • ZZ 11 & GE CX: Бермудские острова (согласно этому документу)
  • KY1-1111: Каймановы острова (согласно этому документу)
  • VG1111: Британские Виргинские острова (согласно этому документу)
  • MSR 1111: Монтсеррат (согласно этому документу)

Всеобъемлющее регулярное выражение для соответствия только британским заморским территориям может выглядеть так:

Смотрите регулярное выражение в использовании здесь.

^((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 Почтовое отделение британских войск

Хотя они были недавно изменены, чтобы лучше соответствовать британской системе почтовых индексов, чтобы BF# (где # представляет число), они считаются необязательными альтернативными почтовыми индексами. Эти почтовые индексы следуют (ред) формат BFPOс последующими 1-4 цифрами:

Смотрите регулярное выражение в использовании здесь

^BFPO ?\d{1,4}$

3.3 Санта?

Есть еще один особый случай с Сантой (как уже упоминалось в других ответах): SAN TA1 действительный почтовый индекс Регулярное выражение для этого очень просто:

^SAN ?TA1$

Похоже, мы будем использовать ^(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})$, который является слегка измененной версией того, что предложено Минглисом выше.

Однако нам необходимо выяснить, какие именно правила, поскольку различные решения, перечисленные выше, по-видимому, применяют различные правила в отношении того, какие буквы разрешены.

После некоторых исследований мы нашли еще немного информации. Очевидно, что страница на govtalk.gov.uk указывает на спецификацию почтовых индексов govtalk-postcodes. Это указывает на XML-схему в XML-схеме, которая предоставляет оператор псевдо-регулярных выражений правил почтового индекса.

Мы взяли это и немного поработали над этим, чтобы дать нам следующее выражение:

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

Это делает пробелы необязательными, но ограничивает вас одним пробелом (замените '&' на '{0,} для неограниченных пробелов). Предполагается, что весь текст должен быть в верхнем регистре.

Если вы хотите использовать нижний регистр с любым количеством пробелов, используйте:

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

Это не распространяется на заморские территории, а только обеспечивает соблюдение формата, а НЕ на существование различных областей. Он основан на следующих правилах:

Может принимать следующие форматы:

  • "ГИР 0АА"
  • A9 9ZZ
  • A99 9ZZ
  • AB9 9ZZ
  • AB99 9ZZ
  • A9C 9ZZ
  • AD9E 9ZZ

Куда:

  • 9 может быть любым однозначным числом.
  • A может быть любой буквой, кроме Q, V или X.
  • B может быть любой буквой, кроме I, J или Z.
  • C может быть любой буквой, кроме I, L, M, N, O, P, Q, R, V, X, Y или Z.
  • D может быть любой буквой, кроме I, J или Z.
  • E может быть любым из A, B, E, H, M, N, P, R, V, W, X или Y.
  • Z может быть любой буквой, кроме C, I, K, M, O или V.

С наилучшими пожеланиями

Colin

Не существует такого понятия, как всеобъемлющее регулярное выражение почтового индекса в Великобритании, способное проверять почтовый индекс. Вы можете проверить, что почтовый индекс имеет правильный формат, используя регулярное выражение; не то, что это на самом деле существует.

Почтовые индексы произвольно сложны и постоянно меняются. Например, исходящий код W1 не имеет и не может иметь каждый номер от 1 до 99 для каждой области почтового индекса.

Вы не можете ожидать, что то, что там сейчас, будет правдой навсегда. Например, в 1990 году почтамт решил, что в Абердине становится немного тесно. Они добавили 0 к концу AB1-5, сделав его AB10-50, а затем создали несколько почтовых индексов между ними.

Всякий раз, когда строится новая улица, создается новый почтовый индекс. Это часть процесса получения разрешения на строительство; местные власти обязаны держать это в курсе с почтовым отделением (не то, что они все делают).

Кроме того, как отметили некоторые другие пользователи, есть специальные почтовые индексы, такие как Girobank, GIR 0AA и один для писем Санте, SAN TA1 - вы, вероятно, не хотите ничего публиковать там, но, похоже, быть покрыт любым другим ответом.

Затем есть почтовые индексы BFPO, которые теперь меняются на более стандартный формат. Оба формата будут действительны. Наконец, есть источник Википедии заморских территорий.

+ ---------- + -------------------------------------- -------- +
| Почтовый индекс | Расположение |
+----------+----------------------------------------------+
| AI-2640  | Ангилья |
| ASCN 1ZZ | Остров Вознесения |
| STHL 1ZZ | Остров Святой Елены |
| TDCU 1ZZ | Тристан-да-Кунья |
| BBND 1ZZ | Британская территория в Индийском океане |
| BIQQ 1ZZ | Британская Антарктическая Территория |
| FIQQ 1ZZ | Фолклендские острова |
| GX11 1AA | Гибралтар |
| PCRN 1ZZ | Острова Питкэрн |
| SIQQ 1ZZ | Южная Георгия и Южные Сандвичевы острова |
| TKCA 1ZZ | Острова Теркс и Кайкос |
+ ---------- + -------------------------------------- -------- + 

Далее, вы должны принять во внимание, что Великобритания "экспортировала" свою систему почтовых индексов во многие места мира. Все, что проверяет почтовый индекс Великобритании, также будет проверять почтовые индексы ряда других стран.

Если вы хотите проверить почтовый индекс Великобритании, самый безопасный способ сделать это - использовать поиск текущих почтовых индексов. Есть несколько вариантов:

  • Ordnance Survey выпускает Code-Point Open под лицензией открытых данных. Это будет немного отставать от времени, но это бесплатно. Это будет (вероятно - я не помню) не включать данные по Северной Ирландии, так как Обследование артиллерийских орудий там не имеет никакого отношения. Картографирование в Северной Ирландии проводится Картографическим управлением Северной Ирландии, и у них есть отдельный платный продукт Pointer. Вы можете использовать это и добавить те, которые не покрываются достаточно легко.

  • Royal Mail выпускает файл адресов с почтовым индексом (PAF), в том числе BFPO, но я не уверен, что Code-Point Open это делает. Он регулярно обновляется, но стоит денег (и они могут быть откровенно плохими). PAF содержит полный адрес, а не только почтовые индексы, и поставляется с собственным Руководством для программистов. Open User User Group (ODUG) в настоящее время лоббирует, чтобы PAF был выпущен бесплатно, вот описание их позиции.

  • Наконец, есть AddressBase. Это сотрудничество между Ordnance Survey, Местными властями, Royal Mail и соответствующей компанией, чтобы создать окончательный каталог всей информации обо всех британских адресах (они также были довольно успешными). Он платный, но если вы работаете с местным органом власти, государственным департаментом или государственной службой, он может им пользоваться бесплатно. Там гораздо больше информации, чем просто почтовые индексы.

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

Регулярное выражение для соответствия действующим почтовым индексам Великобритании. В почтовой системе Великобритании не все буквы используются во всех позициях (то же самое с регистрационными номерами транспортных средств), и существуют различные правила, регулирующие это. Это регулярное выражение учитывает эти правила. Подробности правил: Первая половина почтового индекса Действительные форматы [AZ] [AZ] [0-9] [AZ] [AZ] [AZ] [0-9] [0-9] [AZ] [0-9] [ 0-9] [AZ] [AZ] [0-9] [AZ] [AZ] [AZ] [AZ] [AZ] [0-9] [AZ] [AZ] [0-9] Исключения Позиция - Первая. Ограничение - QVX не используется Положение - Второе. Ограничение - IJZ не используется, кроме как в позиции GIR 0AA - третье. Ограничение - AEHMNPRTVXY используется только Position - Forth. Ограничение - ABEHMNPRVWXY Вторая половина почтового индекса Допустимые форматы [0-9] [AZ] [AZ] Исключения Позиция - Второй и Третий. Ограничение - CIKMOV не используется

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

Я посмотрел некоторые из приведенных выше ответов, и я бы рекомендовал не использовать шаблон из ответа @Dan (c. 15 декабря 2010 г.), поскольку он неверно помечает почти 0,4% действительных почтовых индексов как недействительные, в то время как другие этого не делают.,

Ordnance Survey предоставляет услугу под названием Code Point Open, которая:

содержит список всех текущих единиц почтового индекса в Великобритании

Я проверил каждое из приведенных выше регулярных выражений по полному списку почтовых индексов (6 июля 13 года) по этим данным, используя 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"

Всего насчитывается 1 686 202 почтовых индексов.

Ниже приведены номера действительных почтовых индексов, которые не соответствуют каждому $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

Конечно, эти результаты относятся только к действительным почтовым индексам, которые неправильно помечены как недействительные. Так:

'^.*$'
# => 0

Я ничего не говорю о том, какой шаблон лучше всего подходит для фильтрации недействительных почтовых индексов.

Большинство ответов здесь не работает для всех почтовых индексов, которые есть в моей базе данных. Я наконец нашел тот, который проверяет со всеми, используя новое регулярное выражение, предоставленное правительством:

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

Этого нет ни в одном из предыдущих ответов, поэтому я публикую его здесь на тот случай, если они отключат ссылку:

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

ОБНОВЛЕНИЕ: обновленное регулярное выражение, как указано Джейми Буллом. Не уверен, что это была моя ошибка при копировании или ошибка в правительственном регулярном выражении, ссылка сейчас не работает...

ОБНОВЛЕНИЕ: Как обнаружили ctwheels, это регулярное выражение работает со вкусом регулярных выражений javascript. Смотрите его комментарий, который работает со вкусом pcre (php).

Согласно этой таблице Википедии

Этот шаблон охватывает все случаи

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

При использовании на Android\Java используйте \\d

Это регулярное выражение, которое Google обслуживает в своем домене http://i18napis.appspot.com/address/data/GB:

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}

Старый пост, но все еще довольно высокий в результатах Google, поэтому думал, что я буду обновлять. Этот документ от 14 октября определяет регулярное выражение почтового индекса Великобритании:

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

от:

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

Документ также объясняет логику этого. Тем не менее, он имеет ошибку (выделено жирным шрифтом), а также позволяет использовать нижний регистр, что, хотя и не является законным, поэтому исправленная версия:

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

Это работает с новыми лондонскими почтовыми индексами (например, W1D 5LH), которых не было в предыдущих версиях.

Почтовые индексы могут быть изменены, и единственный верный способ проверить почтовый индекс - это иметь полный список почтовых индексов и посмотреть, есть ли он там.

Но регулярные выражения полезны, потому что они:

  • просты в использовании и реализации
  • короткие
  • быстро бегать
  • довольно просты в обслуживании (по сравнению с полным списком почтовых индексов)
  • по-прежнему ловить большинство ошибок ввода

Но регулярные выражения, как правило, трудно поддерживать, особенно для тех, кто их не придумал. Так и должно быть:

  • настолько легко понять, насколько это возможно
  • относительно будущее

Это означает, что большинство регулярных выражений в этом ответе недостаточно хороши. Например, я вижу это [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

Для меня это правильный баланс между проверкой в ​​максимально возможной степени, но в то же время перспективой и возможностью легкого обслуживания.

В течение последнего дня я искал регулярное выражение для почтового индекса в Великобритании и наткнулся на эту тему. Я работал над большинством приведенных выше предложений, и ни одно из них не сработало для меня, поэтому я пришел к своему собственному регулярному выражению, которое, насколько мне известно, фиксирует все действительные почтовые индексы Великобритании по состоянию на январь 13 года (согласно последней литературе из Королевская Почта).

Регулярное выражение и несколько простых проверок почтового кода PHP-кода размещены ниже. ПРИМЕЧАНИЕ:- Он позволяет использовать нижний или верхний регистр почтовых индексов и аномалию GIR 0AA, но для устранения более вероятного наличия пробела в середине введенного почтового индекса он также использует простое str_replace для удаления пробела перед тестированием. против регулярного выражения Любые расхождения, помимо этого, и в самой Королевской почте даже не упоминаются о них в их литературе (см. http://www.royalmail.com/sites/default/files/docs/pdf/programmers_guide_edition_7_v5.pdf и начните читать со страницы 17).!

Примечание: в собственной литературе Royal Mail (ссылка выше) есть небольшая двусмысленность в отношении 3-й и 4-й позиций и исключений, если эти символы являются буквами. Я связался с Royal Mail напрямую, чтобы выяснить это и своими словами: "Письмо в 4-й позиции Внешнего кода в формате AANA NAA не имеет исключений, а исключения 3-й позиции применяются только к последней букве Исходящего кода с Формат АНА НАА." Прямо изо рта лошади!

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

    }

?>

Я надеюсь, что это поможет любому, кто сталкивается с этой темой, ищет решение.

Вот регулярное выражение, основанное на формате, указанном в документах, которые связаны с ответом marcj:

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

Единственная разница между этим и спецификациями состоит в том, что последние 2 символа не могут быть в [CIKMOV] согласно спецификациям.

Редактировать: вот еще одна версия, которая проверяет наличие ограничений на конечный символ.

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

Некоторые из приведенных выше регулярных выражений немного ограничены. Обратите внимание на подлинный почтовый индекс: "W1K 7AA" потерпит неудачу, учитывая правило "Позиция 3 - только AEHMNPRTVXY используется", так как "K" будет запрещено.

регулярное выражение:

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

Кажется немного более точным, см. Статью в Википедии, озаглавленную "Почтовые индексы в Великобритании".

Обратите внимание, что это регулярное выражение требует только заглавные буквы.

Главный вопрос заключается в том, ограничиваете ли вы ввод данных пользователем только теми существующими почтовыми кодами, или просто пытаетесь запретить пользователям вводить полный мусор в поля формы. Правильно подобрать каждый возможный почтовый индекс и проверить его на будущее - сложная задача, и, вероятно, она того не стоит, если вы не являетесь HMRC.

Я хотел простое регулярное выражение, где можно разрешить слишком много, но не запретить действительный почтовый индекс. Я пошел с этим (вход является обрезанной / обрезанной строкой):

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

Длина от 5 до 7 (не считая пробелов) означает, что мы допускаем как можно более короткие почтовые индексы, такие как "L1 8JQ", так и самые длинные, такие как "OL14 5ET".

РЕДАКТИРОВАТЬ: изменил 8 на 7, чтобы мы не позволяли 8-символьные почтовые индексы.

Хотя здесь много ответов, я не доволен ни одним из них. Большинство из них просто сломаны, слишком сложны или просто сломаны.

Я посмотрел на ответ @ctwheels и нашел его очень понятным и правильным; мы должны поблагодарить его за это. Однако для меня снова слишком много "данных" для чего-то такого простого.

К счастью, мне удалось получить базу данных с более чем 1 миллионом активных почтовых индексов только для Англии, и я сделал небольшой сценарий PowerShell для тестирования и оценки результатов.

Спецификации Великобритании: почтового индексаДействительный формат почтового индекса .

Это «мое» регулярное выражение:

      ^([a-zA-Z]{1,2}[a-zA-Z\d]{1,2})\s(\d[a-zA-Z]{2})$

Коротко, просто и мило. Даже самые неопытные могут понять, что происходит.

Объяснение:

      ^ asserts position at start of a line
    1st Capturing Group ([a-zA-Z]{1,2}[a-zA-Z\d]{1,2})
        Match a single character present in the list below [a-zA-Z]
        {1,2} matches the previous token between 1 and 2 times, as many times as possible, giving back as needed (greedy)
        a-z matches a single character in the range between a (index 97) and z (index 122) (case sensitive)
        A-Z matches a single character in the range between A (index 65) and Z (index 90) (case sensitive)
        Match a single character present in the list below [a-zA-Z\d]
        {1,2} matches the previous token between 1 and 2 times, as many times as possible, giving back as needed (greedy)
        a-z matches a single character in the range between a (index 97) and z (index 122) (case sensitive)
        A-Z matches a single character in the range between A (index 65) and Z (index 90) (case sensitive)
        \d matches a digit (equivalent to [0-9])
        \s matches any whitespace character (equivalent to [\r\n\t\f\v ])
    2nd Capturing Group (\d[a-zA-Z]{2})
        \d matches a digit (equivalent to [0-9])
        Match a single character present in the list below [a-zA-Z]
        {2} matches the previous token exactly 2 times
        a-z matches a single character in the range between a (index 97) and z (index 122) (case sensitive)
        A-Z matches a single character in the range between A (index 65) and Z (index 90) (case sensitive)
$ asserts position at the end of a line

Результат (почтовые индексы проверены):

      TOTAL OK: 1469193
TOTAL FAILED: 0
-------------------------------------------------------------------------
Days              : 0
Hours             : 0
Minutes           : 5
Seconds           : 22
Milliseconds      : 718
Ticks             : 3227185939
TotalDays         : 0.00373516891087963
TotalHours        : 0.0896440538611111
TotalMinutes      : 5.37864323166667
TotalSeconds      : 322.7185939
TotalMilliseconds : 322718.5939

Я использую следующее регулярное выражение, которое я проверял по всем действующим британским почтовым индексам. Оно основано на рекомендуемых правилах, но сжато настолько, насколько это разумно, и не использует никаких специальных правил регулярных выражений для конкретного языка.

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

Предполагается, что почтовый индекс был преобразован в верхний регистр и не имеет начальных или конечных символов, но примет необязательный пробел между исходным кодом и incode.

Специальный почтовый индекс "GIR0 0AA" исключен и не будет подтвержден, поскольку он не входит в официальный список почтовых индексов почтового отделения и, насколько мне известно, не будет использоваться в качестве зарегистрированного адреса. Добавление его должно быть тривиальным в качестве особого случая, если это необходимо.

Основные правила:

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

Почтовые коды в Великобритании (или почтовые индексы, как они называются) состоят из пяти-семи буквенно-цифровых символов, разделенных пробелом. Правила, определяющие, какие символы могут появляться на определенных позициях, довольно сложны и чреваты исключениями. Поэтому только что показанное регулярное выражение придерживается основных правил.

Полные правила:

Если вам нужно регулярное выражение, которое помечает все поля для правил почтового индекса за счет читабельности, то вы идете:

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

Источник: https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9781449327453/ch04s16.html

Проверено на базе данных наших клиентов и выглядит совершенно точно.

Вот как мы имеем дело с проблемой почтового индекса в Великобритании:

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

Объяснение:

  • ожидайте 1 или 2 аз-чара, верхний или нижний штраф
  • ожидать 1 или 2 числа
  • ожидайте 0 или 1 аз символ, верхний или нижний штраф
  • разрешено дополнительное пространство
  • ожидать 1 число
  • ожидать 2 аз, верхний или нижний штраф

Это получает большинство форматов, затем мы используем базу данных, чтобы проверить, является ли почтовый индекс реальным, эти данные управляются openpoint https://www.ordnancesurvey.co.uk/opendatadownload/products.html

надеюсь это поможет

Этот позволяет пустые места и табуляцию с обеих сторон, если вы не хотите, чтобы проверка не прошла, а затем обрежьте ее с другой стороны.

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

Чтобы проверить почтовый индекс в допустимом формате в соответствии с руководством программиста 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})$

Все почтовые индексы на doogal.co.uk совпадают, кроме тех, которые больше не используются.

Добавление ? после пробела и использования нечувствительного к регистру соответствия, чтобы ответить на этот вопрос:

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

Первая половина почтового индекса Действительные форматы

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

Исключения
Положение 1 - QVX не используется
Позиция 2 - IJZ не используется, за исключением GIR 0AA
Положение 3 - используется только AEHMNPRTVXY
Положение 4 - ABEHMNPRVWXY

Вторая половина почтового индекса

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

Исключения
Позиция 2+3 - CIKMOV не используется

Помните, что не все возможные коды используются, поэтому этот список является необходимым, но не достаточным условием для действительного кода. Может быть проще сопоставить список всех действительных кодов?

Путем эмпирического тестирования и наблюдения, а также подтверждения с помощью https://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom, вот моя версия регулярного выражения Python, которая правильно анализирует и проверяет почтовый индекс Великобритании:

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

Это простое регулярное выражение имеет группы захвата. Он не включает все проверки законных почтовых индексов Великобритании, а учитывает только позиции букв и цифр.

Вот как я бы использовал это в коде:

@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

Вот модульные тесты:

@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)

Чтобы добавить в этот список более практичное регулярное выражение, которое я использую, которое позволяет пользователю ввести 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}))$

Это регулярное выражение позволяет использовать заглавные и строчные буквы с необязательным пробелом между

С точки зрения разработчиков программного обеспечения это регулярное выражение полезно для программного обеспечения, где адрес может быть необязательным. Например, если пользователь не хочет указывать свой адрес

Нам дали спецификацию:

Почтовые индексы Великобритании должны быть в одной из следующих форм (с одним исключением, см. Ниже): 
    § A9 9AA 
    § A99 9AA
    § AA9 9AA
    § AA99 9AA
    § A9A 9AA
    § AA9A 9AA
где A представляет буквенный символ, а 9 представляет числовой символ.
Дополнительные правила применяются к буквенным символам, а именно:
    § Символ в позиции 1 не может быть Q, V или X
    § Символ в позиции 2 не может быть I, J или Z
    § Символ в позиции 3 не может быть I, L, M, N, O, P, Q, R, V, X, Y или Z
    § Символ в позиции 4 не может быть C, D, F, G, I, J, K, L, O, Q, S, T, U или Z
    § Символы в двух самых правых позициях не могут быть C, I, K, M, O или V
Единственным исключением, которое не следует этим общим правилам, является почтовый индекс "GIR 0AA", который является специальным действительным почтовым индексом.

Мы придумали это:

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

Но обратите внимание - это позволяет любое количество пробелов между группами.

Посмотрите на код Python на этой странице:

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

Я должен разобрать почтовый индекс. Требование довольно простое; Я должен разобрать почтовый индекс в outcode и (необязательно) incode. Хорошая новость заключается в том, что мне не нужно выполнять какую-либо проверку - мне просто нужно разобрать то, что мне было предоставлено, в смутной форме. Я не могу предположить много о моем импорте с точки зрения форматирования, то есть регистр и встроенные пробелы. Но это не плохие новости; Плохая новость в том, что я должен делать все это в RPG.:-(

Тем не менее, я добавил маленькую функцию Python, чтобы прояснить свое мышление.

Я использовал его для обработки почтовых индексов для меня.

Здесь вы можете найти несколько полезных ссылок, в зависимости от того, какой язык вы используете:

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

Принятый ответ отражает правила, заданные Royal Mail, хотя в регулярном выражении есть опечатка. Похоже, что эта опечатка была также на сайте gov.uk (как и на странице архива XML).

В формате A9A 9AA правила разрешают использование символа P в третьей позиции, а регулярное выражение запрещает это. Правильное регулярное выражение будет:

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

Сокращение этого приводит к следующему регулярному выражению (которое использует синтаксис 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})

Он также включает в себя необязательный пробел между первым и вторым блоком.

У меня есть регулярное выражение для проверки почтового индекса в Великобритании.

Это работает для всех типов почтовых индексов, внутренних или внешних

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

Это работает для всех типов форматов.

Пример:

AB10 --------------------> ТОЛЬКО НАРУЖНЫЙ ПОСТКОД

A1 1AA------------------> КОМБИНАЦИЯ (НАРУЖНОГО И ВНУТРЕННЕГО) ОТКРЫТИЯ

WC2A--------------------> ВНЕШНИЙ

Ниже метод проверит почтовый индекс и предоставит полную информацию

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!"}
Другие вопросы по тегам