219

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

火柴

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

没有匹配

  • aWC2H 7LT
  • WC2H 7LTa
  • WC2H

我该如何解决这个问题?

4

33 回答 33

242

我建议查看英国政府邮政编码数据标准 [链接现已失效;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})

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

于 2008-10-02T23:13:26.197 回答
167

我最近在 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。这是因为他们已经锚定了第一个选项的开始和第二个选项的结束(彼此独立),正如上面的正则表达式中所指出的那样。

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

同样,第一个选项没有锚定到 line 的末尾$,因此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表示数字),并且它以Aor以外的任何内容开头Z,它将失败。

这意味着它将匹配A1A 1AAand Z1A 1AA,但不匹配B1A 1AA

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

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

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

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

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

我发誓他们在网上公布之前甚至没有测试过这个东西。他们使错误的字符集成为可选的。他们在[0-9]选项 2(第 9 组)的第四个子选项中做出了选项。这允许正则表达式匹配格式不正确的邮政编码,例如AAA 1AA.

要解决此问题,请将下一个字符类改为可选(并随后使集合[0-9]匹配一次):

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

问题 5 - 性能

此正则表达式的性能极差。首先,他们将最不可能匹配的模式选项放在GIR 0AA开头。与任何其他邮政编码相比,有多少用户可能拥有此邮政编码;可能永远不会?这意味着每次使用正则表达式时,都必须先用尽该选项,然后再继续下一个选项。要查看性能如何受到影响,请检查原始正则表达式在翻转选项(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. Fixing the UK Government's Regex的简化也已在此处应用):

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

^([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. Fixing the UK Government's Regex中的模式:

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

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

以及关于2. 简化模式

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

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

3.1 英国海外领土

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

  • AI-1111: 安圭拉
  • ASCN 1ZZ: 阿森松岛
  • STHL 1ZZ: 圣赫勒拿
  • TDCU 1ZZ: 特里斯坦·达库尼亚
  • BBND 1ZZ: 英属印度洋领地
  • BIQQ 1ZZ: 英属南极领地
  • FIQQ 1ZZ: 福克兰群岛
  • GX11 1ZZ: 直布罗陀
  • PCRN 1ZZ: 皮特凯恩群岛
  • SIQQ 1ZZ: 南乔治亚岛和南桑威奇群岛
  • TKCA 1ZZ: 特克斯和凯科斯群岛
  • BFPO 11: 阿克罗蒂里和德凯利亚
  • ZZ 11& GE CX:百慕大(根据本文件
  • KY1-1111:开曼群岛(根据本文件
  • VG1111:英属维尔京群岛(根据本文件
  • MSR 1111:蒙特塞拉特(根据本文件

仅匹配英国海外领土的包罗万象的正则表达式可能如下所示:

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

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

3.2 英军邮局

尽管它们最近已更改为更好地与英国邮政编码系统保持一致BF#(其中#代表数字),但它们被认为是可选的替代邮政编码。这些邮政编码遵循(ed)的格式BFPO,后跟 1-4 位数字:

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

^BFPO ?\d{1,4}$

3.3 圣诞老人?

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

^SAN ?TA1$
于 2018-08-16T21:08:16.177 回答
86

看起来我们将要使用^(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 Schema 中的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”</li>
  • 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 之外的任何字母。

最良好的祝愿

科林

于 2011-08-31T15:02:35.620 回答
47

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

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

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

每当建立一条新街道时,就会创建一个新的邮政编码。这是获得建造许可的过程的一部分;地方当局有义务与邮局保持更新(不是他们都这样做)。

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

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

+----------+-------------------------- --------+
| 邮编 | 位置 |
+----------+-------------------------- --------+
| AI-2640 | 安圭拉 |
| ASCN 1ZZ | 阿森松岛 |
| STHL 1ZZ | 圣赫勒拿 |
| TDCU 1ZZ | 特里斯坦达库尼亚 |
| BBND 1ZZ | 英属印度洋领地 |
| BIQQ 1ZZ | 英属南极领地 |
| FIQQ 1ZZ | 福克兰群岛 |
| GX11 1AA | 直布罗陀 |
| PCRN 1ZZ | 皮特凯恩群岛 |
| SIQQ 1ZZ | 南乔治亚岛和南桑威奇群岛 |
| TKCA 1ZZ | 特克斯和凯科斯群岛 |
+----------+-------------------------- --------+

接下来,您必须考虑到英国将其邮政编码系统“出口”到世界许多地方。任何验证“英国”邮政编码的东西也将验证许多其他国家的邮政编码。

如果您想验证英国邮政编码,最安全的方法是使用当前邮政编码查找。有多种选择:

  • Ordnance Survey在开放数据许可下发布Code-Point Open 。它会稍微落后于时代,但它是免费的。这将(可能 - 我不记得)不包括北爱尔兰数据,因为军械调查在那里没有职权范围。北爱尔兰的测绘由北爱尔兰军械测量局进行,他们有自己的独立的、付费的指针产品。您可以使用它并附加一些不太容易涵盖的内容。

  • Royal Mail 发布Postcode Address File (PAF),其中包括 BFPO,我不确定 Code-Point Open 是否会这样做。它会定期更新,但要花钱(有时他们可能会非常刻薄)。PAF 包括完整的地址而不仅仅是邮政编码,并带有自己的程序员指南。开放数据用户组 (ODUG) 目前正在游说免费发布 PAF,这是他们的立场描述

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

于 2013-06-10T12:36:03.253 回答
22
^([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 位置 - 第二。Contraint - IJZ 不使用,除了 GIR 0AA 位置 - 第三。约束 - AEHMNPRTVXY 仅使用位置 - Forth。Contraint - ABEHMNPRVWXY 邮政编码的后半部分 有效格式 [0-9][AZ][AZ] 例外位置 - 第二和第三。约束 - CIKMOV 未使用

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

于 2008-10-02T23:12:53.980 回答
21

我查看了上面的一些答案,我建议不要使用@Dan 的答案 (c. Dec 15 '10)中的模式,因为它错误地将几乎 0.4% 的有效邮政编码标记为无效,而其他的则没有.

Ordnance Survey 提供名为 Code Point Open 的服务,该服务:

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

我使用以下数据针对完整的邮政编码列表(2013 年 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

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

于 2013-07-06T22:18:33.060 回答
13

这里的大多数答案不适用于我数据库中的所有邮政编码。我终于找到了一个使用政府提供的新正则表达式验证所有人的方法:

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

更新:更新了 Jamie Bull 指出的正则表达式。不确定是我的错误复制还是政府正则表达式中的错误,链接现在关闭了......

更新:正如 ctwheels 所发现的,此正则表达式适用于 javascript 正则表达式风格。请参阅他对 pcre (php) 风格的评论。

于 2013-05-10T15:41:40.223 回答
13

根据这个维基百科表

在此处输入图像描述

此模式涵盖所有情况

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

于 2015-04-23T10:07:34.440 回答
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)。

于 2014-11-12T12:34:55.077 回答
11

这是 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}
于 2013-04-11T15:44:09.900 回答
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-04-29T21:52:50.683 回答
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>";

    }

?>

我希望它可以帮助遇到此线程寻找解决方案的其他人。

于 2013-01-10T12:22:03.210 回答
7

这是一个基于文档中指定格式的正则表达式,这些格式链接到 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}$/
于 2011-06-08T09:10:14.570 回答
5

上面的一些正则表达式有点限制。请注意真正的邮政编码:鉴于上述规则“位置 3 - 仅使用 AEHMNPRTVXY”,“W1K 7AA”将失败,因为“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,否则可能不值得。

于 2011-01-25T11:44:17.530 回答
5

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

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

这允许使用最短的邮政编码,如“L1 8JQ”以及最长的邮政编码,如“OL14 5ET”。

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

于 2017-12-01T09:00:54.533 回答
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 char,上限或下限罚款
  • 允许的可选空间
  • 期望 1 个数字
  • 预计 2 az,上限或下限罚款

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

希望这可以帮助

于 2014-08-07T07:43:58.097 回答
4

基本规则:

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

针对我们的客户数据库进行了测试,看起来非常准确。

于 2015-01-23T10:47:47.023 回答
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})

它假定邮政编码已转换为大写并且没有前导或尾随字符,但将接受 outcode 和 incode 之间的可选空格。

特殊的“GIR0 0AA”邮政编码被排除在外,并且不会验证,因为它不在邮局的官方邮政编码列表中,据我所知,不会用作注册地址。如果需要,作为特殊情况添加它应该是微不足道的。

于 2015-11-09T14:03:46.917 回答
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 - IJZ 未使用,GIR 0AA 除外
位置 3 - 仅使用 AEHMNPRTVXY
位置 4 - ABEHMNPRVWXY

邮政编码的后半部分

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

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

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

于 2008-10-02T23:13:30.627 回答
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" ]
于 2015-03-27T13:44:37.443 回答
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*$)
于 2016-01-04T14:41:22.310 回答
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}))$

这个正则表达式允许大写和小写字母之间有一个可选的空格

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

于 2015-09-23T09:35:19.857 回答
2

通过经验测试和观察,以及通过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)
于 2020-04-25T17:56:27.463 回答
1

看看这个页面上的python代码:

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

我有一些邮政编码解析要做。要求很简单;我必须将邮政编码解析为输出代码和(可选)输入代码。好消息是我不必执行任何验证 - 我只需以一种模糊的智能方式切碎提供给我的东西。我不能在格式方面假设我的导入,即大小写和嵌入空格。但这不是坏消息。坏消息是我必须在 RPG 中完成这一切。:-(

尽管如此,我还是把一些 Python 函数放在一起来澄清我的想法。

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

于 2009-10-21T11:44:33.150 回答
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-------->外

于 2012-05-15T12:14:09.323 回答
1

虽然这里有很多答案,但我对其中任何一个都不满意。它们中的大多数只是简单地损坏,太复杂或刚刚损坏。

我查看了@ctwheels的答案,发现它非常具有解释性和正确性;我们必须为此感谢他。然而,对我来说又一次太多的“数据”,对于这么简单的事情。

幸运的是,我设法获得了一个仅包含英格兰超过 100 万个活动邮政编码的数据库,并制作了一个小型 PowerShell 脚本来测试和基准测试结果。

英国邮政编码规范:有效的邮政编码格式

这是“我的”正则表达式:

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

简短、简单、甜美。即使是最没有经验的人也能理解发生了什么。

解释:

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

结果(检查邮政编码):

TOTAL OK: 1469193
TOTAL FAILED: 0
-------------------------------------------------------------------------
Days              : 0
Hours             : 0
Minutes           : 5
Seconds           : 22
Milliseconds      : 718
Ticks             : 3227185939
TotalDays         : 0.00373516891087963
TotalHours        : 0.0896440538611111
TotalMinutes      : 5.37864323166667
TotalSeconds      : 322.7185939
TotalMilliseconds : 322718.5939
于 2021-11-02T06:29:27.523 回答
0

我们得到了一个规格:

英国邮政编码必须采用以下形式之一(有一种例外,见下文):
    § 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

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

于 2012-08-08T12:57:05.657 回答
0

接受的答案反映了皇家邮政给出的规则,尽管正则表达式中有错字。这个错字似乎也出现在 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})

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

于 2015-03-31T08:00:40.447 回答
0

我在几乎所有变体和批量传输 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})$
于 2017-11-15T17:16:11.123 回答
0

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

const isValidUKPostcode = 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,
            message: 'It is a valid postcode'
        };
    } catch (error) {
        return { error: true , message: 'Invalid postcode'};
    }
};
console.log(isValidUKPostcode('GU348RR'))
{isValid: true, formattedPostcode: "GU34 8RR", error: false, message: "It is a valid postcode"}
console.log(isValidUKPostcode('sdasd4746asd'))
{error: true, message: "Invalid postcode!"}
valid_postcode('787898523')
result => {error: true, message: "Invalid postcode"}
于 2019-03-09T23:30:00.287 回答
-1

我需要一个可以在 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;
于 2017-05-04T22:10:47.820 回答
-1

我从一个 XML 文档中窃取了它,它似乎涵盖了所有没有硬编码 GIRO 的情况:

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

(忽略大小写的 Ruby 语法)

于 2019-05-14T16:09:01.030 回答
-1

我今天为英国邮政编码验证做了正则表达式,据我所知,它适用于所有英国邮政编码,如果你放一个空格或者你不放一个空格,它就可以工作。

^((([a-zA-Z][0-9])|([a-zA-Z][0-9]{2})|([a-zA-Z]{2}[0-9])|([a-zA-Z]{2}[0-9]{2})|([A-Za-z][0-9][a-zA-Z])|([a-zA-Z]{2}[0-9][a-zA-Z]))(\s*[0-9][a-zA-Z]{2})$)

让我知道是否有它不涵盖的格式

于 2021-09-21T12:38:27.377 回答