Мне нужно регулярное выражение, которое будет проверять полный сложный почтовый индекс Великобритании только внутри входной строки. Все необычные формы почтовых индексов должны быть покрыты так же, как и обычные. Например:
Спички
Не совпадает
Как мне решить эту проблему?
Приведенная ссылка не работает для форматов «AA1A 1AA». Ссылка: dhl.com.tw/content/dam/downloads/tw/express/forms/…
Если вы просто хотите проверить почтовый индекс, мы предлагаем бесплатную (требуется регистрация) конечную точку REST API для проверки - developers.alliescomputing.com/postcoder-web-api/address-loo kup /…
Хороший вопрос. Я думаю, что стоило бы включить центральные почтовые индексы Манчестера, такие как "M1 3HZ", в ваш список необычных примеров, которым необходимо соответствовать. Многие люди не знают о комбинациях цифр 1 буква 1.





^([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
Понятия не имею, почему люди проголосовали против этого ответа - это правильное регулярное выражение
Регулярное выражение не работает для почтовых индексов «YO31» и «YO31 1» в Javascript.
Я не думаю, что это правильно, поскольку данное регулярное выражение противоречит описанию и предполагает, что у вас могут быть почтовые индексы, начинающиеся с 0-9, чего вы не можете
Это регулярное выражение не работает примерно с 6000 действительными почтовыми индексами, поэтому я бы не рекомендовал его. См. мой ответ.
это не работает с любым почтовым индексом в нижнем регистре или без места для меня
@Dancer Чтобы эти регулярные выражения даже дистанционно управлялись, они, как правило, поддерживают почтовые индексы в верхнем или нижнем регистре, но не оба сразу. В документации везде используются заглавные буквы. С точки зрения проверки, вы должны написать его для поддержки одного и при необходимости изменить регистр. Что касается проблемы с пространством, в документации указано: «Первая часть, или Внешний код, отделена от второй части, Внутреннего кода, одним пробелом» - поэтому пространство является обязательным.
Я бы порекомендовал взглянуть на Стандарт данных правительства Великобритании для почтовых индексов [ссылка теперь мертва; архив 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 этой странице. У кого-нибудь есть исходное регулярное выражение?
И этот регистр с необязательным пробелом между двумя сегментами (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})
Было бы неплохо привести фактическое регулярное выражение к ответу, поскольку страницы, похоже, истекают каждый год ...
Не похоже, что даже Королевская почта (переключитесь на вкладку «Поиск адресов») может найти этот почтовый индекс, поэтому я могу понять, почему регулярное выражение не работает - это совсем новый почтовый индекс? Во всех этих случаях окончание на «К» не допускается.
Не работает в элементе управления RegularExpressionValidator в ASP.Net
Я ошибаюсь, думая, что это не стандартное регулярное выражение? Я не узнаю синтаксис [A-Z-[QVX]].
Не соответствует EX31 3JB
Обратите внимание, что это регулярное выражение предназначено для XML-схемы, которая, очевидно, немного отличается от других разновидностей регулярных выражений.
@artbristol Спасибо, что указали на это. синтаксис класса символов, который он использует означает, что это не будет работать в большинстве других вариантов.
Я все время нахожу действительные почтовые индексы, которые не соответствуют этому шаблону. Например, N1P 1AA кажется действительным, но не соответствует. Возможно, нам следует указать на это в ответе, поскольку это серьезная проблема (она может блокировать регистрацию пользователей). Обычно вы предпочитаете более расслабленный подход, чем потерю клиентов.
@CristianVrabie После небольшого разговора (и обращения в почтовое отделение за разъяснениями) У Дэна Соло, кажется, самое точное и современное регулярное выражение.
Я не могу заставить это работать в JavaScript. Работает ли он только с определенными механизмами регулярных выражений?
Вот версия Javascript (не эквивалентная приведенной выше, но работает): [A-Za-z] {1,2} [0-9] [A-Za-z0-9]? \ S? [0-9 ] [ABD-HJLNP-UW-Zabd-hjl np-uw-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})$
Это взято из 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})$
Я думаю, что регулярное выражение правительства Великобритании неверно. Раздел «[A-Za -z] [A-Ha-hJ-Yj-y] [0- 9]? [A-Za-z]» разрешает исходящий код AAA, насколько я могу видеть, 3 буквы без номера не являются допустимым исходящим кодом (за исключением GIR, который уже обрабатывается в начале регулярного выражения)
@zeocrash Я тоже обнаружил эту проблему. Я исправил этот ответ, учитывая, что за него проголосовали более 150 раз, и предоставил исправленную версию в мой собственный ответ.
Многие из этих регулярных выражений бессмысленно сложны. Нет причин, по которым вам нужно иметь регулярное выражение, которое проверяет верхний и нижний регистр. Просто введите строку в верхнем регистре, и вдруг [A-Ha-hJ-Yj-y] станет [A-HJ-Y].
Это полезно, однако, например, @GerardBrull - я вижу, что многие почтовые индексы не распознаются этим, например GU25 4SZ, G12 8EU, EH3 8DT, N7 7EL, OL5 0HQ - какие-нибудь советы?
Используя ваше регулярное выражение, единственные почтовые индексы, которые не прошли мои тесты, - это те, которые начинаются с NPT, но я думаю, что они больше не используются
Первая половина почтового индекса. Допустимые форматы.
Исключения
Позиция 1 - QVX не используется
Положение 2 - IJZ не используется, кроме GIR 0AA
Позиция 3 - используется только AEHMNPRTVXY
Позиция 4 - ABEHMNPRVWXY
Вторая половина почтового индекса
Исключения
Позиция 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.
Похоже, что почта переехала, но правительство несколько отстает :(
Я использую этот: "^ ([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%!
Вот регулярное выражение, основанное на формате, указанном в документах, связанных с ответом 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 используется редко и т. д. В зависимости от положения символа.
Это может не иметь значения, если вы хотите проверить синтаксис. Как отмечали многие другие, только поиск в актуальной базе данных становится почти правильным, и даже тогда возникает проблема, насколько актуальна база данных. Итак, для меня это регулярное выражение для проверки синтаксиса ясное, простое и полезное.
Похоже, мы собираемся использовать ^(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}))$
Это не распространяется на заморские территории и только обеспечивает соблюдение формата, а НЕ существование различных областей. В его основе лежат следующие правила:
Может принимать следующие форматы:
Где:
С наилучшими пожеланиями
Колин
Отличный ответ, добавил я в заморских ^(([gG][iI][rR] {0,}0[aA]{2})|(([aA][sS][cC][nN]|[sS][tT][hH][lL]|[tT][dD][cC][uU]|[bB][bB][nN][dD]|[bB][iI][qQ][qQ]|[fF][iI][qQ][qQ]|[pP][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-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,} вместо * для неограниченного необязательного пространства?
У меня есть регулярное выражение для проверки почтового индекса Великобритании.
Это работает для всех типов почтовых индексов, как внутренних, так и внешних.
^((([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.
Я искал регулярное выражение почтового индекса Великобритании в течение последнего дня или около того и наткнулся на эту тему. Я проделал свой путь через большинство предложений выше, и ни одно из них не сработало для меня, поэтому я придумал собственное регулярное выражение, которое, насколько мне известно, захватывает все действительные почтовые индексы Великобритании по состоянию на январь 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>";
}
?>
Я надеюсь, что это поможет всем, кто сталкивается с этой веткой в поисках решения.
Мне было бы любопытно узнать, какие почтовые индексы не соответствуют опубликованным?
Я не могу дать вам конкретный почтовый индекс (без доступа к полному списку PAF), но почтовые индексы в формате ANA NAA потенциально не работают, поскольку буквы P и Q разрешены в 3-й позиции, а почтовые индексы в формате AANA NAA потенциально могут также терпят неудачу, поскольку 4-я позиция допускает все буквы (регулярное выражение, указанное в принятом ответе выше, не учитывает ни одно из них). Как я уже сказал, я следую только текущему совету Королевской почты - во время ответа выше, возможно, это регулярное выражение было полностью совместимо.
Спасибо за внимание - я вижу, что «P», кажется, добавлен как приемлемый в третьей позиции (из вашего связанного документа), но не Q - но где вы читаете, что «4-я позиция допускает все буквы»? Насколько я могу судить, в документе вообще не упоминается «четвертая позиция», поэтому я бы прочитал это как «третью букву независимо от фактического положения».
Хороший вопрос по поводу Q - ошибка с моей стороны! Однако это становится вопросом интерпретации 3-й / 4-й буквы, и я не уверен, кто из нас прав. В документе 1-я и 2-я буквы конкретно упоминаются как «первая / вторая альфа-позиция», а 3-я буква - только как «третья позиция». Я интерпретировал это как третий символ (буквенный или числовой) в почтовом индексе, таком как A1B 2DE. В противном случае, конечно, B в приведенном выше примере потенциально может быть переведена как буква во второй альфа-позиции, что в любом случае делает опубликованное регулярное выражение неправильным?
Согласился, что в любом случае нет упоминания о 4-м, но я думаю, что я придерживаюсь своей логики через ... (Также только что заметил, что в утвержденном ответе выше есть еще один список исключений букв для 4-го символа в формате почтового индекса AANA - ни один из них вообще не упоминается в литературе Королевской почты). Может, мне нужно связаться с Королевской Почтой, чтобы разобраться с этим раз и навсегда. В ближайшее время мы получим их последнюю версию PAF.
Только что получил ответ от службы поддержки Royal Mail, и моя интерпретация правил, по-видимому, верна. Буква в 4-й позиции внешнего кода (например, AANA NAA) не имеет исключений, а исключения для 3-й позиции применяются только к последней букве (например, ANA NAA). Прямо изо рта лошади.
Полезно знать - вы можете обновить свой ответ этой информацией;)
@DanSolo Это регулярное выражение вернет истинное совпадение для первой половины действительного почтового индекса без внутреннего кода, например SW1A или BD25 без второй половины (или, по крайней мере, для меня)
Это регулярное выражение, которое 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}
Большинство ответов здесь не работали для всех почтовых индексов, которые есть в моей базе данных. Я наконец нашел тот, который подтверждается всеми, используя новое регулярное выражение, предоставленное правительством:
Этого нет ни в одном из предыдущих ответов, поэтому я размещаю его здесь на случай, если они отключат ссылку:
^([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})$ - заметьте разницу ;-)
Пятно! Обновил свой ответ. Спасибо!
Это единственный ответ, который работал в 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, чтобы найти более одного результата, и для обоих, чтобы найти результат без разделителя пробелов.
@ctwheels это регулярное выражение для вкуса javascript. Если ваша ссылка не работает, вы выбираете javascript, она будет работать. Это отличный улов, и я обновлю свой ответ.
@ 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})|(([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}))$ - исправленное регулярное выражение.
@ JesúsCarrera регулярное выражение, которое я опубликовал выше, является исправленным регулярным выражением для многих разновидностей (не только PCRE). Это исправленная версия для PHP, JavaScript, Python и т. д.
@ctwheels Я вижу, как регулярное выражение из документации gov не работает для ваших примеров, я обновлю, чтобы использовать вашу модификацию, которая, кажется, работает лучше, однако я вижу, что ваша модификация соответствует правильным почтовым индексам только в js-вкусе, вы это проверили?
@ JesúsCarrera Не хочу больше отнимать у вас время, но есть ли простой способ изменить это, чтобы просто проверить и сопоставить первую часть почтового индекса, например L2, OX12, SW4? Я так безнадежен в Regex.
@ 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]), но был бы признателен, если бы вы или кто-либо другой могли поискать неисправности :)
Не существует такой вещи, как исчерпывающее регулярное выражение почтового индекса Великобритании, которое могло бы использовать подтверждение как почтовый индекс. Вы можете проверить правильность формата почтового индекса с помощью регулярного выражения; не то чтобы он действительно существует.
Почтовые индексы произвольно сложны и постоянно меняются. Например, в исходящем коде 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 и соответствующей компанией для создания полного каталога всей информации обо всех британских адресах (они также были довольно успешными). Это платно, но если вы работаете с местным органом власти, правительственным департаментом или государственной службой, им можно пользоваться бесплатно. Здесь гораздо больше информации, чем просто почтовые индексы.
поиск звучит интересно
Хотя это не тот ответ, который искала операционист, он, вероятно, самый полезный. Это побудит меня ослабить правила проверки, которые я собираюсь выполнить.
Я изучил некоторые из приведенных выше ответов, и я бы рекомендовал не использовать шаблон из @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
Я ничего не говорю о том, какой шаблон лучше всего подходит для фильтрации недействительных почтовых индексов.
Разве это не то, что я говорю в своем ответе, и если вы идете по пути опровержения, вам, вероятно, следует сделать их все и постоянно обновлять, если кто-то изменит свой ответ? Если нет, по крайней мере, укажите дату последнего редактирования ответа, из которого вы его взяли, чтобы люди могли видеть, изменилось ли оно с тех пор.
Честная оценка. Отредактировал соответственно. Я думаю, это добавляет к обсуждению, чтобы указать, что большинство этих шаблонов не исключают ни один из кодов CPO, но это делает ответ, получивший наибольшее количество голосов (действительное регулярное выражение). Будущие читатели: имейте в виду, что мои результаты, вероятно, устарели.
Почтовые индексы могут быть изменены, и единственный верный способ проверить почтовый индекс - это иметь полный список почтовых индексов и посмотреть, есть ли он там.
Но регулярные выражения полезны, потому что они:
Но регулярные выражения, как правило, сложно поддерживать, особенно для тех, кто вообще не придумал их. Так должно быть:
Это означает, что большинство регулярных выражений в этом ответе недостаточно хороши. Например. Я вижу, что [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 Он также соответствует, когда другие символы добавляются в начало или конец, например. aSW1A 1AAasfg мне подошел (я не отрицал, хотя, похоже, это можно легко исправить)
вот как мы решаем проблему с почтовым индексом Великобритании:
^([A-Za-z]{1,2}[0-9]{1,2}[A-Za-z]?[ ]?)([0-9]{1}[A-Za-z]{2})$
Объяснение:
Это получает большинство форматов, затем мы используем базу данных, чтобы проверить, действительно ли почтовый индекс реален, эти данные управляются открытой точкой https://www.ordnancesurvey.co.uk/opendatadownload/products.html
надеюсь это поможет
Это допускает недопустимый формат AANNA NAA.
Следовательно, часть ответа «Это получает большинство форматов». :)
Старый пост, но все еще довольно высокий в результатах 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})$
из:
В документе также объясняется его логика. Однако он содержит ошибку (выделен жирным шрифтом), а также допускает строчные буквы, что, хотя и не является нормальным, поэтому исправленная версия:
^(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), чего не было в предыдущих версиях.
Похоже, что ошибка, которую вы выделили жирным шрифтом, была исправлена в документе, но я по-прежнему предпочитаю ваше регулярное выражение, так как его легче читать.
Единственное, что я бы сказал, это сделать пространство необязательным, изменив его на \ 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-9][A-Za-z]{2}))$ - исправленное регулярное выражение.
Основные правила:
^[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)$
Протестировано по базе данных наших клиентов и кажется совершенно точным.
Чтобы проверить почтовый индекс в допустимом формате согласно руководство программиста 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})
Чтобы добавить в этот список более практичное регулярное выражение, которое я использую, которое позволяет пользователю вводить 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) с примерами, описанными в исходном вопросе
Это неработающее регулярное выражение правительства Великобритании, и оно не может проверить некоторые допустимые форматы.
@ctwheels Привет, пожалуйста, укажите неверный почтовый индекс, спасибо.
Например. AAA 1AA не является допустимым форматом: см. мой ответ для объяснения и исправления.
Мне нужна была версия, которая работала бы в 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, когда тестировал вчера.
Метод ниже проверит почтовый индекс и предоставит полную информацию
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)
@axrwkr, это бесполезно