RegEx для сопоставления почтовых индексов Великобритании

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

Спички

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

Не совпадает

  • aWC2H 7LT
  • WC2H 7LTa
  • WC2H

Как мне решить эту проблему?

@axrwkr, это бесполезно

Kieran Benton 25.06.2013 15:13
Проверка почтового индекса Великобритании - JavaScript и PHP I couldn't get the accepted answer to match valid postcodes but I found this and it does match valid postcodes. For client side validation, the JavaScript version can be used as is, for server side validation, rewriting the JavaScript as C# is fairly straightforward. It even reformats the postcode to have a space, so if you enter a postcode as W1A1AA, in addition to validating, it will reformat it to W1A 1AA. It even deals with unusual postcodes in various British territories.
user2985029 25.06.2013 15:38

Приведенная ссылка не работает для форматов «AA1A 1AA». Ссылка: dhl.com.tw/content/dam/downloads/tw/express/forms/…

Anthony Scaife 18.07.2014 14:24

Если вы просто хотите проверить почтовый индекс, мы предлагаем бесплатную (требуется регистрация) конечную точку REST API для проверки - developers.alliescomputing.com/postcoder-web-api/address-loo‌ kup /…

Stephen Keable 14.01.2015 12:56

Хороший вопрос. Я думаю, что стоило бы включить центральные почтовые индексы Манчестера, такие как "M1 3HZ", в ваш список необычных примеров, которым необходимо соответствовать. Многие люди не знают о комбинациях цифр 1 буква 1.

Martin Joiner 10.12.2017 18:05
Многие ответы здесь основаны на сломанном регулярном выражении, предоставленном правительством Великобритании.. For a breakdown of these issues, please refer to мой ответ здесь
ctwheels 17.08.2018 00:22
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
198
6
210 185
30
Перейти к ответу Данный вопрос помечен как решенный

Ответы 30

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

Regular expression to match valid UK postcodes. In the UK postal system not all letters are used in all positions (the same with vehicle registration plates) and there are various rules to govern this. This regex takes into account those rules. Details of the rules: First half of postcode Valid formats [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] Exceptions Position - First. Contraint - QVX not used Position - Second. Contraint - IJZ not used except in GIR 0AA Position - Third. Constraint - AEHMNPRTVXY only used Position - Forth. Contraint - ABEHMNPRVWXY Second half of postcode Valid formats [0-9][A-Z][A-Z] Exceptions Position - Second and Third. Contraint - CIKMOV not used

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

Понятия не имею, почему люди проголосовали против этого ответа - это правильное регулярное выражение

Ollie 25.03.2010 20:59

Регулярное выражение не работает для почтовых индексов «YO31» и «YO31 1» в Javascript.

Pratik Khadloya 08.12.2011 05:12

Я не думаю, что это правильно, поскольку данное регулярное выражение противоречит описанию и предполагает, что у вас могут быть почтовые индексы, начинающиеся с 0-9, чего вы не можете

Luigi Plinge 27.04.2012 00:05

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

RichardTowers 07.07.2013 02:20

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

Dancer 17.12.2014 20:01

@Dancer Чтобы эти регулярные выражения даже дистанционно управлялись, они, как правило, поддерживают почтовые индексы в верхнем или нижнем регистре, но не оба сразу. В документации везде используются заглавные буквы. С точки зрения проверки, вы должны написать его для поддержки одного и при необходимости изменить регистр. Что касается проблемы с пространством, в документации указано: «Первая часть, или Внешний код, отделена от второй части, Внутреннего кода, одним пробелом» - поэтому пространство является обязательным.

Zhaph - Ben Duguid 03.08.2015 20:08
Ответ принят как подходящий

Я бы порекомендовал взглянуть на Стандарт данных правительства Великобритании для почтовых индексов [ссылка теперь мертва; архив 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), и они предоставляют более строгий тест, который вы можете попробовать.

Похоже, новый домен .gov удалось 404 этой странице. У кого-нибудь есть исходное регулярное выражение?

Tom 01.07.2010 16:41

И этот регистр с необязательным пробелом между двумя сегментами (GIR 0AA) | ((([AZ- [QVX]] [0-9] [0-9]?) | (([AZ- [QVX]] [AZ- [IJZ]] [0-9‌] [0-9]?) | (([AZ- [QVX‌]] [0-9] [A-HJKSTUW]) | ‌ ([AZ- [ QVX]] [AZ- [IJ‌ Z]] [0-9] [ABEHMNPRVWX‌ Y])))) \ s? [0-9] [AZ- [‌ CIKMOV]] {2})

gb2d 06.06.2012 22:06

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

pauloya 21.11.2012 21:03

Не похоже, что даже Королевская почта (переключитесь на вкладку «Поиск адресов») может найти этот почтовый индекс, поэтому я могу понять, почему регулярное выражение не работает - это совсем новый почтовый индекс? Во всех этих случаях окончание на «К» не допускается.

Zhaph - Ben Duguid 12.01.2013 18:44

Не работает в элементе управления RegularExpressionValidator в ASP.Net

user692942 07.03.2013 17:14

Я ошибаюсь, думая, что это не стандартное регулярное выражение? Я не узнаю синтаксис [A-Z-[QVX]].

RichardTowers 07.07.2013 01:30

Не соответствует EX31 3JB

gyozo kudor 25.07.2013 11:43

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

artbristol 06.08.2013 17:14

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

RichardTowers 20.08.2013 13:51

Я все время нахожу действительные почтовые индексы, которые не соответствуют этому шаблону. Например, N1P 1AA кажется действительным, но не соответствует. Возможно, нам следует указать на это в ответе, поскольку это серьезная проблема (она может блокировать регистрацию пользователей). Обычно вы предпочитаете более расслабленный подход, чем потерю клиентов.

Cristian Vrabie 07.09.2013 19:53

@CristianVrabie После небольшого разговора (и обращения в почтовое отделение за разъяснениями) У Дэна Соло, кажется, самое точное и современное регулярное выражение.

Zhaph - Ben Duguid 17.02.2014 22:23

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

NickG 27.03.2014 13:57

Вот версия Javascript (не эквивалентная приведенной выше, но работает): [A-Za-z] {1,2} [0-9] [A-Za-z0-9]? \ S? [0-9 ] [ABD-HJLNP-UW-Zabd-hjl‌ np-uw-z] {2}

gb2d 29.06.2015 16:10

разрешает ли какое-либо из этих решений пустое пространство вокруг почтового индекса?

SuperUberDuper 06.11.2015 14:56

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

Mike 21.04.2016 17:25

Собственно поменяли: Массовая передача данных: ^([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})$

wieczorek1990 24.06.2016 17:22

Это взято из gov.uk/government/publications/…, соответствующего BS7666, и он работает с JavaScript: ^([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})$

Gerard Brull 12.12.2017 20:15

Я думаю, что регулярное выражение правительства Великобритании неверно. Раздел «[A-Za‌ -z] [A-Ha-hJ-Yj-y] [0-‌ 9]? [A-Za-z]» разрешает исходящий код AAA, насколько я могу видеть, 3 буквы без номера не являются допустимым исходящим кодом (за исключением GIR, который уже обрабатывается в начале регулярного выражения)

zeocrash 16.01.2018 17:46

@zeocrash Я тоже обнаружил эту проблему. Я исправил этот ответ, учитывая, что за него проголосовали более 150 раз, и предоставил исправленную версию в мой собственный ответ.

ctwheels 17.08.2018 00:19

Многие из этих регулярных выражений бессмысленно сложны. Нет причин, по которым вам нужно иметь регулярное выражение, которое проверяет верхний и нижний регистр. Просто введите строку в верхнем регистре, и вдруг [A-Ha-hJ-Yj-y] станет [A-HJ-Y].

Daniel Quinn 28.10.2019 15:06

Это полезно, однако, например, @GerardBrull - я вижу, что многие почтовые индексы не распознаются этим, например GU25 4SZ, G12 8EU, EH3 8DT, N7 7EL, OL5 0HQ - какие-нибудь советы?

user6122500 17.12.2020 16:03

Используя ваше регулярное выражение, единственные почтовые индексы, которые не прошли мои тесты, - это те, которые начинаются с NPT, но я думаю, что они больше не используются

Dimitris Thomas 11.02.2021 01:30

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

  • [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] [0-9] [A-Z]
  • [A-Z] [0-9]

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

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

  • [0–9] [A – Z] [A – Z]

Исключения
Позиция 2 + 3 - ЦИКМОВ не используется

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

Взгляните на код Python на этой странице:

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

I've got some postcode parsing to do. The requirement is pretty simple; I have to parse a postcode into an outcode and (optional) incode. The good new is that I don't have to perform any validation - I just have to chop up what I've been provided with in a vaguely intelligent manner. I can't assume much about my import in terms of formatting, i.e. case and embedded spaces. But this isn't the bad news; the bad news is that I have to do it all in RPG. :-(

Nevertheless, I threw a little Python function together to clarify my thinking.

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

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

Похоже, что почта переехала, но правительство несколько отстает :(

Zhaph - Ben Duguid 25.01.2011 15:10

Я использую этот: "^ ([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}) $ "Мне это нравится, потому что он позволяет использовать верхний и нижний регистры и делает пространство необязательным - лучше для удобства использования, если не на 100%!

bigtv 22.03.2011 22:14

Вот регулярное выражение, основанное на формате, указанном в документах, связанных с ответом 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}$/

С почтовым индексом Великобритании гораздо сложнее, чем просто принять A-Z - Q никогда не допускается, V используется редко и т. д. В зависимости от положения символа.

Zhaph - Ben Duguid 14.01.2013 18:04

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

Rick-777 05.09.2014 16:45

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

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

После некоторого исследования мы нашли дополнительную информацию. Очевидно, страница на govtalk.gov.uk указывает вам на спецификацию почтового индекса govtalk-почтовые индексы. Это указывает на схему 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.

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

Колин

Отличный ответ, добавил я в заморских ^(([gG][iI][rR] {0,}0[aA]{2})|(([aA][sS][cC][nN]|[sS][tT][hH][lL]|[tT][dD][c‌​C][uU]|[bB][bB][nN][‌​dD]|[bB][iI][qQ][qQ]‌​|[fF][iI][qQ][qQ]|[p‌​P][cC][rR][nN]|[sS][‌​iI][qQ][qQ]|[iT][kK]‌​[cC][aA]) {0,}1[zZ]{2})|((([a-pr-uwyzA-PR-UWYZ][a-hk-yxA-HK-XY]?[0-9][‌​0-9]?)|(([a-pr-uwyzA‌​-PR-UWYZ][0-9][a-hjk‌​stuwA-HJKSTUW])|([a-‌​pr-uwyzA-PR-UWYZ][a-‌​hk-yA-HK-Y][0-9][abe‌​hmnprv-yABEHMNPRV-Y]‌​))) {0,}[0-9][abd-hjlnp-uw-zABD-HJLNP-UW-Z]{2}))$

David Bradshaw 22.11.2016 20:12

Зачем указывать {0,} вместо * для неограниченного необязательного пространства?

Code Animal 01.08.2017 13:52

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

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

^((([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-------------------->ONLY OUTER POSTCODE

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

WC2A-------------------->OUTER

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

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.

Мы пришли к такому выводу:

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

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

paulslater19, к сожалению, ваше решение позволяет использовать почтовые индексы A99A 9AA.

user1854089 26.11.2012 20:59

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

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

Примечание: В собственной литературе Королевской почты (ссылка выше) есть небольшая двусмысленность в отношении 3-й и 4-й позиций и исключения, если эти символы являются буквами. Я напрямую связался с Royal Mail, чтобы прояснить это, и их собственными словами: «Буква в 4-й позиции Outward Code в формате AANA NAA не имеет исключений, а исключения 3-й позиции применяются только к последней букве Outward Code с формат ANA NAA. " Прямо изо рта лошади!

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

    }

?>

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

Мне было бы любопытно узнать, какие почтовые индексы не соответствуют опубликованным?

Zhaph - Ben Duguid 12.01.2013 18:37

Я не могу дать вам конкретный почтовый индекс (без доступа к полному списку PAF), но почтовые индексы в формате ANA NAA потенциально не работают, поскольку буквы P и Q разрешены в 3-й позиции, а почтовые индексы в формате AANA NAA потенциально могут также терпят неудачу, поскольку 4-я позиция допускает все буквы (регулярное выражение, указанное в принятом ответе выше, не учитывает ни одно из них). Как я уже сказал, я следую только текущему совету Королевской почты - во время ответа выше, возможно, это регулярное выражение было полностью совместимо.

Dan Solo 14.01.2013 15:09

Спасибо за внимание - я вижу, что «P», кажется, добавлен как приемлемый в третьей позиции (из вашего связанного документа), но не Q - но где вы читаете, что «4-я позиция допускает все буквы»? Насколько я могу судить, в документе вообще не упоминается «четвертая позиция», поэтому я бы прочитал это как «третью букву независимо от фактического положения».

Zhaph - Ben Duguid 14.01.2013 18:00

Хороший вопрос по поводу Q - ошибка с моей стороны! Однако это становится вопросом интерпретации 3-й / 4-й буквы, и я не уверен, кто из нас прав. В документе 1-я и 2-я буквы конкретно упоминаются как «первая / вторая альфа-позиция», а 3-я буква - только как «третья позиция». Я интерпретировал это как третий символ (буквенный или числовой) в почтовом индексе, таком как A1B 2DE. В противном случае, конечно, B в приведенном выше примере потенциально может быть переведена как буква во второй альфа-позиции, что в любом случае делает опубликованное регулярное выражение неправильным?

Dan Solo 14.01.2013 19:42

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

Dan Solo 14.01.2013 19:43

Только что получил ответ от службы поддержки Royal Mail, и моя интерпретация правил, по-видимому, верна. Буква в 4-й позиции внешнего кода (например, AANA NAA) не имеет исключений, а исключения для 3-й позиции применяются только к последней букве (например, ANA NAA). Прямо изо рта лошади.

Dan Solo 16.01.2013 21:47

Полезно знать - вы можете обновить свой ответ этой информацией;)

Zhaph - Ben Duguid 17.01.2013 01:19

@DanSolo Это регулярное выражение вернет истинное совпадение для первой половины действительного почтового индекса без внутреннего кода, например SW1A или BD25 без второй половины (или, по крайней мере, для меня)

decvalts 07.08.2015 16:19

Это регулярное выражение, которое Google обслуживает в своем домене 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}

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

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

^([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})|(([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})$ - заметьте разницу ;-)

Jamie Bull 16.05.2014 17:08

Пятно! Обновил свой ответ. Спасибо!

Jesús Carrera 18.05.2014 13:54

Это единственный ответ, который работал в regexr.com и Notepad ++. Хотя мне пришлось изменить его на ([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}) (удалили ^ и $ и добавили ? после пробела) для regexr.com, чтобы найти более одного результата, и для обоих, чтобы найти результат без разделителя пробелов.

mythofechelon 27.02.2015 02:59

@ctwheels это регулярное выражение для вкуса javascript. Если ваша ссылка не работает, вы выбираете javascript, она будет работать. Это отличный улов, и я обновлю свой ответ.

Jesús Carrera 14.08.2018 14:06

@ JesúsCarrera, приношу свои извинения, я разместил не ту ссылку. Я перепечатаю его ниже с правильной ссылкой и удалю старую после.

ctwheels 14.08.2018 17:19

Регулярное выражение, опубликованное в документации, по своей сути неверно. Все выражение должно быть заключено в не захватывающую группу (?:), а затем вокруг нее должны быть размещены якоря. Смотрите, это не удается здесь. Для получения дополнительной информации см. мой ответ здесь. ^(?:([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 14.08.2018 17:34

@ JesúsCarrera регулярное выражение, которое я опубликовал выше, является исправленным регулярным выражением для многих разновидностей (не только PCRE). Это исправленная версия для PHP, JavaScript, Python и т. д.

ctwheels 14.08.2018 17:35

@ctwheels Я вижу, как регулярное выражение из документации gov не работает для ваших примеров, я обновлю, чтобы использовать вашу модификацию, которая, кажется, работает лучше, однако я вижу, что ваша модификация соответствует правильным почтовым индексам только в js-вкусе, вы это проверили?

Jesús Carrera 15.08.2018 12:53

@ JesúsCarrera Не хочу больше отнимать у вас время, но есть ли простой способ изменить это, чтобы просто проверить и сопоставить первую часть почтового индекса, например L2, OX12, SW4? Я так безнадежен в Regex.

Freddie Ergatoudis 15.08.2018 14:26

@ JesúsCarrera уверен, что это что-то вроде этого: ^([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]), но был бы признателен, если бы вы или кто-либо другой могли поискать неисправности :)

Freddie Ergatoudis 15.08.2018 15:15

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

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

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

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

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

Затем есть почтовые индексы BFPO, которые теперь переход на более стандартный формат. Оба формата будут действительными. Наконец, заморские территории source 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                     |
+----------+----------------------------------------------+

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

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

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

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

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

поиск звучит интересно

SuperUberDuper 06.11.2015 14:59

Хотя это не тот ответ, который искала операционист, он, вероятно, самый полезный. Это побудит меня ослабить правила проверки, которые я собираюсь выполнить.

John Hunt 11.08.2016 16:09

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

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

contains a list of all the current postcode units in Great Britain

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

Всего 1686202 почтовых индексов.

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

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

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

Ben 10.07.2013 10:04

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

RichardTowers 10.07.2013 22:47

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

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

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

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

  • как можно проще понять
  • относительно будущее

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

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

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

Jon 19.08.2014 15:23

@Jon Он также соответствует, когда другие символы добавляются в начало или конец, например. aSW1A 1AAasfg мне подошел (я не отрицал, хотя, похоже, это можно легко исправить)

decvalts 07.08.2015 16:00

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

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

Объяснение:

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

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

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

Это допускает недопустимый формат AANNA NAA.

ctwheels 16.08.2018 21:49

Следовательно, часть ответа «Это получает большинство форматов». :)

Alex Stephens 03.05.2019 11:07

Старый пост, но все еще довольно высокий в результатах 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), чего не было в предыдущих версиях.

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

Professor of programming 27.09.2015 03:01

Единственное, что я бы сказал, это сделать пространство необязательным, изменив его на \ s? поскольку пространство не является требованием для удобства чтения.

Professor of programming 27.09.2015 03:07

Регулярное выражение, опубликованное в документации, по своей сути неверно. Все выражение должно быть заключено в не захватывающую группу (?:), а затем вокруг нее должны быть размещены якоря. Смотрите, это не удается здесь. Для получения дополнительной информации см. мой ответ здесь. ^(?:([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 14.08.2018 17:34

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

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

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

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

Принятый ответ отражает правила 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-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

Я нашел это наиболее читаемый ответ, хотя он ищет только форму почтового индекса, а не действительные коды в соответствии с решениями, которые берут информацию с веб-сайта gov.uk, но этого достаточно для моего варианта использования. Немного поиграв с ним (на python), я преобразовал его в немного более компактное, но эквивалентное регулярное выражение, которое также позволяет использовать дополнительное пространство: ([a-zA-Z] (?: (?: [A-zA- Z]? \ D [a-zA-Z]) | (?: \ D {1,2}) | (?: [A-zA-Z] \ ‌ d {1,2})) \ W? [0-9] [a-z‌ AZ] {2})

Richard J 21.07.2015 20:58

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

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

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

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

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

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

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

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

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

Это единственный шаблон, который работал у меня с использованием C# (System.Text.RegularExpressions) с примерами, описанными в исходном вопросе

MattjeS 02.05.2017 15:55

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

ctwheels 16.08.2018 21:50

@ctwheels Привет, пожалуйста, укажите неверный почтовый индекс, спасибо.

Matas Vaitkevicius 17.08.2018 05:28

Например. AAA 1AA не является допустимым форматом: см. мой ответ для объяснения и исправления.

ctwheels 17.08.2018 09:36

Мне нужна была версия, которая работала бы в SAS с 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}$

Тестовые примеры и примечания:

/* 
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 &. Notes &0.;
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;

То, что я нашел почти во всех вариациях и регулярном выражении из PDF-файла с массовой передачей, и то, что есть на сайте Википедии, - это то, что специально для регулярного выражения Википедии должно быть ^ после первого | (вертикальная полоса). Я понял это, тестируя AA9A 9AA, потому что в противном случае проверка формата для A9A 9AA подтвердит его. Например, проверка для EC1D 1BB, который должен быть недопустимым, возвращается действительным, потому что C1D 1BB является допустимым форматом.

Вот что я придумал для хорошего регулярного выражения:

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

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

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

Это позволяет использовать как самые короткие почтовые индексы, такие как «L1 8JQ», так и самые длинные, такие как «OL14 5ET».

Поскольку он позволяет использовать до 8 символов, он также допускает неправильные 8-значные почтовые индексы, если нет места: «OL145ETX». Но опять же, это упрощенное регулярное выражение, когда этого достаточно.

О, мои извинения. Я думаю, что пропустил / i, когда тестировал вчера.

Llama 14.03.2018 14:20

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

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

Я украл это из XML-документа, и, похоже, он охватывает все случаи без жестко запрограммированного GIRO:

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

(Синтаксис Ruby с игнорированием регистра)

Путем эмпирического тестирования и наблюдения, а также подтверждения с помощью https://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom#Validation, вот моя версия регулярного выражения 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)

Другие вопросы по теме