RegEx用于匹配英国邮政编码


185

我正在使用一个正则表达式,它将仅在输入字符串内验证完整的复杂英国邮政编码。所有不常见的邮政编码形式都必须像往常一样覆盖。例如:

火柴

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

没有比赛

  • aWC2H 7LT
  • WC2H 7LTa
  • WC2H

我该如何解决这个问题?


2
@axrwkr似乎没有帮助
Kieran Benton

8
英国邮政编码验证-JavaScript和PHP我无法获得与有效邮政编码匹配的可接受答案,但我发现了这一点,并且确实与有效邮政编码匹配。对于客户端验证,可以直接使用JavaScript版本,对于服务器端验证,以C#重写JavaScript非常简单。它甚至将邮政编码重新格式化为具有空格,因此,如果您输入邮政编码为W1A1AA,则除了进行验证外,还会将其重新格式化为W1A 1AA。它甚至处理英国各个地区的不寻常的邮政编码。

2
提供的链接不适用于“ AA1A 1AA”格式。参考:dhl.com.tw/content/dam/downloads/tw/express/forms/…–
Anthony Scaife

1
如果你只是想验证邮政编码,我们提供免费的(注册需要)验证REST API终点- developers.alliescomputing.com/postcoder-web-api/address-lookup/...
斯蒂芬Keable

1
好问题。我认为值得在您需要匹配的不常见示例列表中包含曼彻斯特中央邮政编码,例如“ M1 3HZ”。许多人不知道1字母1数字组合。
马丁·乔纳

Answers:


207

我建议您查看英国政府数据标准中的邮政编码[现在链接已消失;XML存档,请参阅Wikipedia进行讨论]。这里有关于数据的简短描述,附加的xml模式提供了一个正则表达式。它可能不完全是您想要的,但将是一个很好的起点。RegEx与XML略有不同,因为给定的定义允许使用A9A 9AA格式的第三位置的P字符。

英国政府提供的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})

正如Wikipedia讨论中指出的那样,这将允许一些非真实的邮政编码(例如,以AA,ZY开头的邮政编码),并且确实提供了您可以尝试的更严格的测试。


52
并且该正则表达式在两个段之间具有可选的空白(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- [IJZ]] [0-9] [ABEHMNPRVWXY])))))\ s?[0-9] [AZ- [CIKMOV]] {2})
gb2d

6
可能需要一个真正的正则表达式来解决这个问题,因为页面似乎每年都会过期...
pauloya 2012年

7
请注意,此正则表达式用于XML Schema,显然,它与其他正则表达式版本略有不同
artbristol 2013年

6
我无法在JavaScript中使用它。它仅适用于某些正则表达式引擎吗?
NickG 2014年

12
实际上,他们更改了它:批量数据传输^([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

85

看来我们将要使用 ^(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-postcodes。这指向XML模式上的XML模式,该模式提供了邮政编码规则的“伪正则表达式”语句。

我们已经对此进行了一些处理,以使我们获得以下表达式:

^((GIR &0AA)|((([A-PR-UWYZ][A-HK-Y]?[0-9][0-9]?)|(([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRV-Y]))) &[0-9][ABD-HJLNP-UW-Z]{2}))$

这使空格成为可选的,但确实将您限制为一个空格(将'&'替换为'{0,}表示无限制的空格)。假定所有文本必须为大写。

如果要允许小写字母,可以使用任意数量的空格,请使用:

^(([gG][iI][rR] {0,}0[aA]{2})|((([a-pr-uwyzA-PR-UWYZ][a-hk-yA-HK-Y]?[0-9][0-9]?)|(([a-pr-uwyzA-PR-UWYZ][0-9][a-hjkstuwA-HJKSTUW])|([a-pr-uwyzA-PR-UWYZ][a-hk-yA-HK-Y][0-9][abehmnprv-yABEHMNPRV-Y]))) {0,}[0-9][abd-hjlnp-uw-zABD-HJLNP-UW-Z]{2}))$

这不包括海外领土,仅强制采用格式,不存在其他区域。它基于以下规则:

可以接受以下格式:

  • “ GIR 0AA”
  • 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以外的任何字母。

最好的祝愿

科林


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

为什么要指定{0,}而不是*无限的可选空间?
Code Animal

75

我最近发布了一个答案,以在英国的邮政编码为R语言这个问题。我发现英国政府的正则表达式模式不正确,无法正常运行验证某些邮政编码。不幸的是,这里的许多答案都是基于这种不正确的模式。

我将在下面概述其中的一些问题,并提供实际可行的修订后的正则表达式。


注意

我的回答(以及一般的正则表达式):

  • 仅验证邮政编码格式
  • 不确保邮政编码合法存在
    • 为此,请使用适当的API!有关更多信息,请参见Ben的答案

如果您不关心正则表达式不好,只想跳到答案,请向下滚动到答案部分。

坏正则表达式

不应使用本节中的正则表达式。

这是英国政府为开发人员提供的失败的正则表达式(不确定此链接将打开多长时间,但是您可以在其批量数据传输文档中看到它):

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

问题

问题1-复制/粘贴

请参阅此处使用的正则表达式

正如许多开发人员可能会做的那样,他们复制/粘贴代码(尤其是正则表达式)并粘贴它们,以期望它们能正常工作。虽然从理论上讲这很好,但在这种特殊情况下会失败,因为从此文档进行复制/粘贴实际上会将一个字符(空格)更改为换行符,如下所示:

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

大多数开发人员要做的第一件事就是删除换行符而无需三思而后行。现在,正则表达式将不匹配包含空格的邮政编码(除了GIR 0AA邮政编码邮政编码除外)。

若要解决此问题,应将换行符替换为空格字符:

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

问题2-边界

请参阅此处使用的正则表达式

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

邮政编码正则表达式锚定了正则表达式。如果像这样的值fooA11 1AA通过,则使用此正则表达式验证邮政编码的任何人都可能会感到惊讶。正如上面的regex所指出的,这是因为它们锚定了第一个选项的开始和第二个选项的结束(彼此独立)。

这意味着^(在行首的断言位置)仅在第一个选项上有效([Gg][Ii][Rr] 0[Aa]{2}),因此第二个选项将验证以邮政编码结尾的任何字符串(不管之前是什么)。

同样,第一个选项也不锚定到该行的末尾$,因此GIR 0AAfoo也被接受。

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

要解决此问题,两个选项都应包装在另一个组(或非捕获组)中,并在其周围放置锚点:

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

问题3-字符集不正确

请参阅此处使用的正则表达式

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

正则表达式在-此处缺少表示字符范围的a。就目前而言,如果邮政编码采用以下格式ANA NAA(其中A代表字母并N代表数字),并且其开头不是A或,Z,则它将失败。

这意味着它将匹配A1A 1AAZ1A 1AA,但不会B1A 1AA

要解决此问题,-应将字符放在相应的字符集中的A和之间Z

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

问题4-错误的可选字符集

请参阅此处使用的正则表达式

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

我发誓他们甚至没有在网络上发布该产品之前就对其进行了测试。他们将错误的字符集设为可选。他们[0-9]在选项2(第9组)的第四个子选项中做出了选择。这允许正则表达式匹配格式错误的邮政编码AAA 1AA

要解决此问题,请将下一个字符类改为可选(然后使该设置[0-9]完全匹配一次):

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

问题5-成效

此正则表达式的性能非常差。首先,他们GIR 0AA在开头放置了最不可能匹配的模式选项。与其他邮政编码相比,有多少用户将可能拥有此邮政编码;可能永远不会?这意味着每次使用正则表达式时,必须先用尽此选项,然后才能继续使用下一个选项。要查看性能如何受到影响,请在翻转选项(22)之后检查原始正则表达式针对同一个正则表达式采取的步骤数(35 )。

性能的第二个问题是由于整个正则表达式的结构方式。如果一个选项失败了,那就没有回头路了。当前正则表达式的结构方式可以大大简化。我将在“ 答案”部分中对此提供修复。

问题6-空格

查看正则表达式在这里使用

本质上,这可能不算是一个问题,但是确实引起了大多数开发人员的关注。正则表达式中的空格不是可选的,这意味着输入邮政编码的用户必须在邮政编码中放置一个空格。这是一个简单的解决方法,只需?在空格后添加使其变为可选即可。请参阅“ 答案”部分以获取修复程序。


回答

1.修复英国政府的正则表达式

修复“ 问题”部分中概述的所有问题并简化模式,可以得到以下更短,更简洁的模式。我们也可以删除大多数组,因为我们要验证整个邮政编码(而不是各个部分):

查看正则表达式在这里使用

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

通过从一种情况(大写或小写)中删除所有范围并使用不区分大小写的标志,可以进一步缩短此时间。注意:某些语言没有一种,因此请使用上面较长的一种。每种语言以不同的方式实现不区分大小写的标志。

请参阅此处使用的正则表达式

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

再次简短地替换[0-9]\d(如果您的正则表达式引擎支持):

请参阅此处使用的正则表达式

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

2.简化模式

在不确保特定字母字符的情况下,可以使用以下内容(请记住1中的简化形式此处还应用了修复英国政府的正则表达式):

请参阅此处使用的正则表达式

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

甚至更进一步,如果您不在乎这种特殊情况GIR 0AA

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

3.复杂的模式

我不建议对邮政编码进行过度验证,因为新的地区,地区和街道可能会在任何时间出现。我建议可能会做的是增加了对边缘情况的支持。存在一些特殊情况,并在此Wikipedia文章中进行了概述。

这是复杂的正则表达式,包括3小节(3.1、3.2、3.3)。

关于1.中的模式。修复英国政府的正则表达式

查看正则表达式在这里使用

^(([A-Z][A-HJ-Y]?\d[A-Z\d]?|ASCN|STHL|TDCU|BBND|[BFS]IQQ|PCRN|TKCA) ?\d[A-Z]{2}|BFPO ?\d{1,4}|(KY\d|MSR|VG|AI)[ -]?\d{4}|[A-Z]{2} ?\d{2}|GE ?CX|GIR ?0A{2}|SAN ?TA1)$

并与2.简化模式有关

查看正则表达式在这里使用

^(([A-Z]{1,2}\d[A-Z\d]?|ASCN|STHL|TDCU|BBND|[BFS]IQQ|PCRN|TKCA) ?\d[A-Z]{2}|BFPO ?\d{1,4}|(KY\d|MSR|VG|AI)[ -]?\d{4}|[A-Z]{2} ?\d{2}|GE ?CX|GIR ?0A{2}|SAN ?TA1)$

3.1英属海外领地

维基百科文章目前指出(某些格式略有简化):

  • AI-1111:安吉拉
  • ASCN 1ZZ:升天岛
  • STHL 1ZZ:圣海伦娜
  • TDCU 1ZZ:Tristan da Cunha
  • BBND 1ZZ: 英属印度洋领地
  • BIQQ 1ZZ:英属南极领地
  • FIQQ 1ZZ: 福克兰群岛
  • GX11 1ZZ:直布罗陀
  • PCRN 1ZZ:皮特凯恩群岛
  • SIQQ 1ZZ:南乔治亚岛和南桑威奇群岛
  • TKCA 1ZZ: 特克斯和凯科斯群岛
  • BFPO 11:阿克罗蒂里和德凯利亚
  • ZZ 11GE CX:百慕大(根据本文档
  • KY1-1111:开曼群岛(根据本文件
  • VG1111:英属维尔京群岛(根据本文件
  • MSR 1111:蒙特塞拉特(根据本文件

仅与英国海外领土匹配的功能全面的正则表达式可能如下所示:

请参阅此处使用的正则表达式

^((ASCN|STHL|TDCU|BBND|[BFS]IQQ|GX\d{2}|PCRN|TKCA) ?\d[A-Z]{2}|(KY\d|MSR|VG|AI)[ -]?\d{4}|(BFPO|[A-Z]{2}) ?\d{2}|GE ?CX)$

3.2英军邮局

尽管最近对其进行了更改,以使其更好地与英国邮政编码系统匹配BF#(其中#代表数字),但它们被视为可选的替代邮政编码。这些邮政编码遵循的格式BFPO,后接1-4位数字:

查看正则表达式在这里使用

^BFPO ?\d{1,4}$

3.3圣诞老人?

圣诞老人还有另一种特殊情况(如其他答案所述):SAN TA1是有效的邮政编码。正则表达式非常简单:

^SAN ?TA1$

4
简化模式是一个非常好的选择。我发现最好不要对正则表达式限制太多,因为这样您就需要确保对正则表达式进行了任何更改,否则您可能会激怒用户。我觉得最好与简化的正则表达式松散匹配以清除明显的错误,然后再进行进一步的检查,例如地址查找(或电子邮件正则表达式时为确认电子邮件),以确认有效性。
詹姆斯·科伊尔

2
出色而详尽的分析。
史蒂夫,

1
如此出色的答案。最终,我选择了第二种简化模式。因为我实际上有一个包含所有英国邮政编码的数据库,所以我只需要第一遍就可以查看地址字符串是否可能包含有效的邮政编码,所以我不在乎误报(因为实际查找会将其根除) ,但我确实关心误报。速度也很重要。
约翰·鲍威尔

英国邮编系统存在很多问题,显然是在计算机时代之前由委员会创建的,但是可变长度和空格问题是最有害的问题之一。我已经看到了各种各样的恐怖方式,包括将邮政编码从E1 5JX填充到E1 5JX,即使用三个空格,以便它与Excel中的SW18 5HA很好地匹配(插入不恰当的不合适的软件来管理地址)。唯一的解决办法理智,恕我直言,是去掉所有的空间,从而使邮政编码是一个字符串的任何地方获得弹性,Solr的,Postgres的等近前
约翰·鲍威尔

45

没有能够验证邮政编码的完整的英国邮政编码正则表达式。您可以使用正则表达式检查邮政编码的格式是否正确;不是说它确实存在。

邮政编码是任意复杂且不断变化的。例如W1,对于每个邮政编码区域,输出代码都不会,也可能永远不会有1到99之间的每个数字。

您不能指望当前永远是真的。例如,1990年,邮局认为阿伯丁有点拥挤。他们在AB1-5的末尾添加了0,使其成为AB10-50,然后在它们之间创建了许多邮政编码。

每当建造新街道时,都会创建新的邮政编码。这是获得构建许可的过程的一部分;地方当局有义务与邮局保持联系(并非全部如此)。

此外,正如许多其他用户所指出的那样,还有一些特殊的邮政编码,例如Girobank,GIR 0AA,以及写给圣诞老人的信,即SAN TA1-您可能不想在此张贴任何东西,但似乎没有被其他答案覆盖。

然后是BFPO邮政编码,现在正在更改为更标准的格式。两种格式都将有效。最后,还有海外领土来源Wikipedia

+ ---------- + -------------------------------------- -------- +
| 邮政编码| 位置|
+ ---------- + -------------------------------------- -------- +
| AI-2640 | 安圭拉|
| ASCN 1ZZ | 升天岛|
| STHL 1ZZ | 圣海伦娜|
| TDCU 1ZZ | Tristan da Cunha |
| BBND 1ZZ | 英属印度洋领地|
| BIQQ 1ZZ | 英属南极领地|
| FIQQ 1ZZ | 福克兰群岛|
| GX11 1AA | 直布罗陀|
| PCRN 1ZZ | 皮特凯恩群岛|
| SIQQ 1ZZ | 南乔治亚岛和南桑威奇群岛|
| TKCA 1ZZ | 特克斯和凯科斯群岛|
+ ---------- + -------------------------------------- -------- +

接下来,您必须考虑到英国将其邮政编码系统“出口”到了世界上的许多地方。验证“英国”邮政编码的所有内容也将验证许多其他国家的邮政编码。

如果要验证英国邮政编码,最安全的方法是使用当前邮政编码的查询。有很多选项:

  • Ordnance Survey 根据开放数据许可发布了Code-Point Open。它会稍微落后于时代,但它是免费的。这(可能-我不记得了)将不包括北爱尔兰的数据,因为军械测量局对此没有意见。北爱尔兰的制图由北爱尔兰的兵器调查进行,并且有其单独的付费的Pointer产品。您可以使用它并添加一些不太容易覆盖的部分。

  • Royal Mail会发布邮政编码地址文件(PAF),其中包括BFPO,我不确定Code-Point Open会这样做。它会定期更新,但要花钱(有时,它们可能是彻头彻尾的意思)。PAF包含完整的地址,而不仅仅是邮政编码,并且附带了自己的《程序员指南》。开放数据用户组(ODUG)当前正在游说免费发布PAF,这是其地位的描述

  • 最后,还有AddressBase。这是兵器测量局,地方当局,皇家邮政和匹配公司之间的合作,以创建有关所有英国地址的所有信息的最终目录(它们也相当成功)。它是付费的,但是如果您与地方政府,政府部门或政府服务部门合作,则可以免费使用。除了包含邮政编码以外,还有更多信息。


查找听起来很有趣
SuperUberDuper

2
尽管这不是操作员所寻找的答案,但它可能是最有用的。这将鼓励我放宽我要执行的检查规则。
约翰·亨特

22

我查看了上面的一些答案,建议不要使用@Dan 答案中的模式(约10年12月15日),因为它错误地将近0.4%的有效邮政编码标记为无效,而其他代码则不。

军械测量局提供称为代码点开放的服务,该服务:

包含英国当前所有邮政编码单位的列表

我使用以下数据对照上述数据的完整列表(13年7月6日)运行了每个正则表达式grep

cat CSV/*.csv |
    # Strip leading quotes
    sed -e 's/^"//g' |
    # Strip trailing quote and everything after it
    sed -e 's/".*//g' |
    # Strip any spaces
    sed -E -e 's/ +//g' |
    # Find any lines that do not match the expression
    grep --invert-match --perl-regexp "$pattern"

共有1,686,202个邮政编码。

以下是 匹配的有效邮政编码数量$pattern

'^([A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]?[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA)$'
# => 6016 (0.36%)
'^(GIR ?0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]([0-9ABEHMNPRV-Y])?)|[0-9][A-HJKPS-UW]) ?[0-9][ABD-HJLNP-UW-Z]{2})$'
# => 0
'^GIR[ ]?0AA|((AB|AL|B|BA|BB|BD|BH|BL|BN|BR|BS|BT|BX|CA|CB|CF|CH|CM|CO|CR|CT|CV|CW|DA|DD|DE|DG|DH|DL|DN|DT|DY|E|EC|EH|EN|EX|FK|FY|G|GL|GY|GU|HA|HD|HG|HP|HR|HS|HU|HX|IG|IM|IP|IV|JE|KA|KT|KW|KY|L|LA|LD|LE|LL|LN|LS|LU|M|ME|MK|ML|N|NE|NG|NN|NP|NR|NW|OL|OX|PA|PE|PH|PL|PO|PR|RG|RH|RM|S|SA|SE|SG|SK|SL|SM|SN|SO|SP|SR|SS|ST|SW|SY|TA|TD|TF|TN|TQ|TR|TS|TW|UB|W|WA|WC|WD|WF|WN|WR|WS|WV|YO|ZE)(\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}))|BFPO[ ]?\d{1,4}$'
# => 0

当然,这些结果仅处理被错误地标记为无效的有效邮政编码。所以:

'^.*$'
# => 0

我没有说关于过滤无效邮政编码的最佳模式。


1
这不是我在回答中所说的吗,如果您沿着不可靠的路线,您可能应该全部完成,并在有人更改答案时保持更新?如果不是,请至少参考您对答案的最后一次编辑日期,以便人们可以查看该答案是否已更改。

有道理。进行了相应的编辑。我认为这增加了讨论的范围,指出这些模式中的大多数不排除任何CPO代码,但是最受支持的(有效的正则表达式)答案却是。未来的读者:请注意,我的结果可能会过时。
RichardTowers

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

正则表达式以匹配有效的英国邮政编码。在英国的邮政系统中,并非在所有位置都使用所有字母(与车辆牌照相同),并且有各种规则来管理。此正则表达式考虑了这些规则。规则的详细信息:邮政编码的前半部分有效格式[AZ] [AZ] [0-9] [AZ] [AZ] [AZ] [0-9] [0-9] [AZ] [0-9] [ 0-9] [AZ] [AZ] [0-9] [AZ] [AZ] [AZ] [AZ] [0-9] [AZ] [AZ] [0-9]例外位置-第一。约束-未使用QVX位置-秒。约束-仅在GIR 0AA位置中未使用IJZ-第三。约束-AEHMNPRTVXY仅用于位置-向前。约束-ABEHMNPRVWXY邮政编码的后一半有效格式[0-9] [AZ] [AZ]异常位置-第二和第三。约束-未使用CIKMOV

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


1
不知道为什么人们不赞成这个答案-这是正确的正则表达式
Ollie

正则表达式不适用于Javscript中的邮政编码“ YO31”和“ YO31 1”。
Pratik Khadloya 2011年

9
我认为这是不正确的,因为给出的正则表达式与描述相矛盾,建议您可以使用以开头的邮政编码0-9,而您不能这样做
Luigi Plinge 2012年

4
此正则表达式在大约6000个有效邮政编码上失败,因此我建议不要这样做。看我的回答
RichardTowers

这在小写或没有空格的情况下对任何邮政编码都失败
Dancer

14

根据此维基百科表格

在此处输入图片说明

该模式涵盖所有情况

(?:[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-zA-Z] {2})
理查德J

14

对于数据库中的所有邮政编码,此处的大多数答案均无效。我终于找到了一个使用政府提供的新正则表达式对所有人进行验证的文件:

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 regex风格一起使用。请参阅他的评论,以了解适合pcre(php)风格的产品。


1
^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$应该是^([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

1
发现!更新了我的答案。谢谢!
耶苏斯·卡雷拉

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可以找到多个结果,并且两个都可以找到没有空格分隔符的结果。
mythofechelon'Feb 26'15

@ctwheels此正则表达式适用于javascript。如果您的失败链接选择了javascript,它将起作用。那是一个很大的收获,我将更新我的答案。
赫苏斯·卡雷拉

1
文档中发布的正则表达式本质上是不正确的。整个表达式应包装在一个非捕获组中(?:),然后在其周围放置锚点。看到这里失败。有关更多信息,请参见此处^(?:([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([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

12

一个旧的帖子,但在谷歌搜索结果中仍然很高,所以以为我会更新。这份10月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)。


看起来您用粗体突出显示的错误已在文档中得到修复,但我仍希望使用正则表达式,因为它更易于阅读。
编程教授

5
我唯一要说的是通过将空格更改为\ 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}))$是校正后的正则表达式。
ctwheels

10

这是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}

10

邮政编码可能会发生变化,并且验证邮政编码的唯一正确方法是拥有完整的邮政编码列表,然后查看是否存在。

但是正则表达式很有用,因为它们:

  • 易于使用和实施
  • 运行快
  • 易于维护(与完整的邮政编码列表相比)
  • 仍然捕获大多数输入错误

但是正则表达式往往很难维护,特别是对于那些一开始没有提出正则表达式的人。因此它必须是:

  • 尽可能容易理解
  • 相对未来的证明

这意味着该答案中的大多数正则表达式都不够好。例如,我可以看到[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

对我来说,这是在尽可能多地进行验证,同时进行面向未来的验证和简化维护之间的正确平衡。


不确定您为什么被否决-这适用于我向其抛出的所有有效邮政编码以及上述许多答案无法正确处理的空格。有人愿意解释为什么吗?
2014年

1
@乔恩它还匹配时,其他字符被附加到开始或结束比如aSW1A 1AAasfg我匹配(我没有downvote虽然,因为它似乎它可以很容易固定)
decvalts

9

我一直在寻找最后一天的英国邮政编码正则表达式,却偶然发现了这个线程。我按照上面的大多数建议进行工作,但没有一个对我有用,因此我想出了自己的正则表达式,据我所知,该正则表达式捕获了13年1月以来所有有效的英国邮政编码(根据来自皇家邮政)。

正则表达式和一些简单的邮政编码检查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位使用AANA NAA格式的字母没有例外,而第3位例外情况仅适用于外发代码的最后一个字母,带有格式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>";

    }

?>

我希望它能帮助遇到此问题的其他任何人寻找解决方案。


1
我很想知道哪些示例邮政编码未通过已发布的示例?
Zhaph-Ben Duguid 2013年

我无法为您提供特定的邮政编码(无法访问完整的PAF列表),但是格式为ANA NAA的邮政编码可能会失败,因为在第三位允许使用字母P和Q,而格式为AANA NAA的邮政编码可能会失败也会失败,因为第4位允许所有字母(上面接受的答案中给出的正则表达式不解释这两个字母)。正如我说的,我只是遵循皇家邮政的最新建议-在上述回答之时,也许正则表达式完全合规。
Dan Solo 2013年

感谢您的注意-我可以看到“ P”似乎已经在第三位置(从您的链接文档中)被添加为可接受的,但不是Q-但是您在哪里读到“第四位置允许所有字母”?据我所知,该文档根本没有提到“第四位”,因此我将其读为“无论实际位置如何,都是第三个字母”。
Zhaph-Ben Duguid 2013年

1
刚刚收到皇家邮政支持小组的回复,我对规则的解释显然是正确的。外向代码第四位的字母(例如AANA NAA)没有例外,第三位例外仅适用于最后一个字母(例如ANA NAA)。直接从马的嘴巴。
Dan Solo

1
@DanSolo此正则表达式将返回一个真正的比赛为一个有效的邮政编码上半年缺少向内代码如SW1ABD25不下半年(或至少它为我做的)
decvalts

7

这是一个正则表达式,基于链接到marcj的答案的文档中指定的格式:

/^[A-Z]{1,2}[0-9][0-9A-Z]? ?[0-9][A-Z]{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

2
如果您想要的是语法检查,那可能无关紧要。正如许多其他人所说的那样,只有在最新数据库中进行查询才几乎是正确的,即使如此,仍然存在数据库最新程度的问题。因此,对我而言,此语法检查器regex清晰,简单且有用。
Rick-777,2014年

5

上面的一些正则表达式有一些限制。注意真正的邮政编码:“ 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})$

似乎更准确一些,请参阅Wikipedia文章“英国的邮政编码”

请注意,此正则表达式仅需要大写字符。

更大的问题是,您是要限制用户输入以仅允许实际存在的邮政编码,还是只是试图阻止用户在表单字段中输入完整的垃圾。正确匹配每个可能的邮政编码,并在以后进行验证,这是一个难题,除非您是HMRC,否则可能不值得。


看起来邮局已经转移了,但政府却落后了一些:(
Zhaph-Ben Duguid 2011年

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,1} [0-9] [ A-Za-z] {2})$“我喜欢它,因为它允许使用大写和小写字母,并使空格可选-如果不是100%正确,则对可用性更好!
bigtv 2011年

4

这是我们一直在处理英国邮政编码问题的方式:

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

说明:

  • 预期1或2个Az字​​符,上限或下限罚款
  • 期望1或2个数字
  • 预期为0或1 AZ字符,上限或下限罚款
  • 允许的可选空间
  • 期待1个号码
  • 预期2 AZ,上限或下限罚款

这将获得大多数格式,然后我们使用db来验证邮政编码是否真实,该数据由openpoint驱动 https://www.ordnancesurvey.co.uk/opendatadownload/products.html

希望这可以帮助


这允许使用格式AANNA NAA,该格式无效。
ctwheels

因此,答案中的“这将获得大多数格式”部分。:)
亚历克斯·史蒂芬斯

4

基本规则:

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

英国的邮政编码(或称邮政编码)由5到7个字母数字字符组成,中间用空格分隔。关于哪些字符可以出现在特定位置的规则相当复杂,并且充满例外。因此,刚刚显示的正则表达式遵循基本规则。

完整规则:

如果您需要一个正则表达式,以牺牲可读性的方式在邮政编码规则的所有方框中打勾,请执行以下操作:

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

经过我们的客户数据库测试,看起来非常准确。


4

我使用已针对所有有效的英国邮政编码测试过的以下正则表达式。它基于建议的规则,但是尽可能地精简,并且不使用任何特定于语言的特殊正则表达式规则。

([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”邮编已排除在外,由于它不在官方邮局的邮编列表中,因此不会生效,据我所知,它将不会用作注册地址。如果需要的话,添加它应该是平凡的事。


4

我想要一个简单的正则表达式,可以允许太多,但不能拒绝有效的邮政编码。我去了(输入是一个剥离/修剪字符串):

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

这样就可以使用最短的邮政编码,例如“ L1 8JQ”,也可以使用最长的邮政编码,例如“ OL14 5ET”。

因为它最多允许8个字符,所以如果没有空格,它还将允许使用不正确的8个字符的邮政编码:“ OL145ETX”。但这又是一个简单的正则表达式,因为这足够好了。


哦,很抱歉 我想我昨天进行测试时错过了/ i。
约翰(John John)

3

邮政编码的前半部分有效格式

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

例外情况
位置1-未使用QVX
位置2-未在GIR 0AA中使用IJZ
位置3-仅使用AEHMNPRTVXY
位置4-ABEHMNPRVWXY

邮编的后半部分

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


位置2 + 3 例外-未使用CIKMOV

请记住,并非所有可能的代码都已使用,因此此列表是有效代码的必要但非充分条件。仅与所有有效代码的列表匹配可能会更容易?


3

根据皇家邮政的程序员指南,检查邮政编码是否为有效格式:

          |----------------------------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上的所有邮政编码匹配,但不再使用的邮政编码除外。

?在空格后添加a 并使用不区分大小写的匹配来回答此问题:

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

3

如果您不想通过验证,则可以在两侧留有空格和制表符,然后在服务器的侧面进行裁切。

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

这是英国政府的正则表达式损坏,无法验证某些有效格式。
ctwheels

@ctwheels您好,请提供失败的邮政编码,谢谢。
Matas Vaitkevicius

例如,AAA 1AA这不是有效的格式:请参阅我的答案以获取解释和修正。
ctwheels

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

此正则表达式允许使用大写字母和小写字母,并且两者之间可以有可选空格

从软件开发人员的角度来看,此正则表达式对于地址可能为可选的软件很有用。例如,如果用户不想提供其地址详细信息


1

看看此页面上的python代码:

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

我要解析一些邮政编码。要求很简单;我必须将邮政编码解析为outcode和(可选)incode。好消息是,我不必执行任何验证-我只需要以隐约的智能方式将所提供的内容砍掉即可。对于格式方面的导入(例如大小写和嵌入式空格),我不能承担太多责任。但这不是坏消息。坏消息是我必须在RPG中完成所有操作。:-(

不过,我将一些Python函数放在一起以阐明自己的想法。

我用它来为我处理邮政编码。


1

我们得到了一个规格:

英国邮政编码必须采用以下格式之一(一种例外,请参见下文): 
    §A9 9AA 
    §A99 9AA
    §AA9 9AA
    §AA99 9AA
    §A9A 9AA
    §AA9A 9AA
其中A代表字母字符,9代表数字字符。
附加规则适用于字母字符,如下所示:
    §位置1的字符可能不是Q,V或X
    §位置2的字符可能不是I,J或Z
    §位置3的字符可能不是I,L,M,N,O,P,Q,R,V,X,Y或Z
    §位置4的字符可能不是C,D,F,G,I,J,K,L,O,Q,S,T,U或Z
    §最右边两个位置的字符可能不是C,I,K,M,O或V
不遵循这些通用规则的一个例外是邮政编码“ GIR 0AA”,这是一种特殊的有效邮政编码。

我们想到了这个:

/^([A-PR-UWYZ][A-HK-Y0-9](?:[A-HJKS-UW0-9][ABEHMNPRV-Y0-9]?)?\s*[0-9][ABD-HJLNP-UW-Z]{2}|GIR\s*0AA)$/i

但请注意-组之间允许有任意数量的空格。


2
paulslater19,很遗憾,您的解决方案允许A99A 9AA邮政编码。

1

我有用于英国邮政编码验证的正则表达式。

这适用于内部或外部的所有类型的邮政编码

^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))) || ^((GIR)[ ]?(0AA))$|^(([A-PR-UWYZ][0-9])[ ]?([0-9][ABD-HJLNPQ-UW-Z]{0,2}))$|^(([A-PR-UWYZ][0-9][0-9])[ ]?([0-9][ABD-HJLNPQ-UW-Z]{0,2}))$|^(([A-PR-UWYZ][A-HK-Y0-9][0-9])[ ]?([0-9][ABD-HJLNPQ-UW-Z]{0,2}))$|^(([A-PR-UWYZ][A-HK-Y0-9][0-9][0-9])[ ]?([0-9][ABD-HJLNPQ-UW-Z]{0,2}))$|^(([A-PR-UWYZ][0-9][A-HJKS-UW0-9])[ ]?([0-9][ABD-HJLNPQ-UW-Z]{0,2}))$|^(([A-PR-UWYZ][A-HK-Y0-9][0-9][ABEHMNPRVWXY0-9])[ ]?([0-9][ABD-HJLNPQ-UW-Z]{0,2}))$

这适用于所有类型的格式。

例:

AB10 -------------------->仅外部邮政编码

A1 1AA ------------------>(内部和外部)邮政编码的组合

WC2A -------------------->外


1

尽管正则表达式中有拼写错误,但可接受的答案反映了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})

它还在第一块和第二块之间包括一个可选空间。


1

我从批量转移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})$

1

通过经验测试和观察,以及通过https://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom#Validation进行确认,这是我的Python regex版本,该版本可正确解析和验证英国邮政编码:

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)

0

我需要一个可以在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 &$10. Notes &$100.;
flag = prxmatch('/^[A-PR-UWYZ](([A-HK-Y]?\d\d?)|(\d[A-HJKPSTUW])|([A-HK-Y]\d[ABEHMNPRV-Y]))\s?\d[ABD-HJLNP-UW-Z]{2}$/',strip(postcode));
cards;
1  EC1A 1BB  Special case 1
1  W1A 0AX   Special case 2
1  M1 1AE    Standard format
1  B33 8TH   Standard format
1  CR2 6XH   Standard format
1  DN55 1PT  Standard format
0  QN55 1PT  Bad letter in 1st position
0  DI55 1PT  Bad letter in 2nd position
0  W1Z 0AX   Bad letter in 3rd position
0  EC1Z 1BB  Bad letter in 4th position
0  DN55 1CT  Bad letter in 2nd group
0  A11A 1AA  Invalid digits in 1st group
0  AA11A 1AA  1st group too long
0  AA11 1AAA  2nd group too long
0  AA11 1AAA  2nd group too long
0  AAA 1AA   No digit in 1st group
0  AA 1AA    No digit in 1st group
0  A 1AA     No digit in 1st group
0  1A 1AA    Missing letter in 1st group
0  1 1AA     Missing letter in 1st group
0  11 1AA    Missing letter in 1st group
0  AA1 1A    Missing letter in 2nd group
0  AA1 1     Missing letter in 2nd group
;
run;

0

下面的方法将检查邮政编码并提供完整的信息

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!"}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.