英国邮政编码正则表达式

8

我希望能够验证英国邮编,最好的情况是以下案例都可以通过:

  1. W1
  2. W12
  3. WC1
  4. WC1A
  5. WC12
  6. W1 6BT
  7. W12 6BT
  8. WC1 6BT
  9. WC1A 6BT
  10. WC12 6BT
  11. W16BT
  12. W126BT
  13. WC16BT
  14. WC1A6BT
  15. WC126BT

我有以下正则表达式模式:

^(GIR 0AA)|(((A[BL]|B[ABDHLNRSTX]?|C[ABFHMORTVW]|D[ADEGHLNTY]|E[HNX]?|F[KY]|G[LUY]?|H[ADGPRSUX]|I[GMPV]|JE|K[ATWY]|L[ADELNSU]?|M[EKL]?|N[EGNPRW]?|O[LX]|P[AEHLOR]|R[GHM]|S[AEGKLMNOPRSTY]?|T[ADFNQRSW]|UB|W[ADFNRSV]|YO|ZE)[1-9]?[0-9]|((E|N|NW|SE|SW|W)1|EC[1-4]|WC[12])[A-HJKMNPR-Y]|(SW|W)([2-9]|[1-9][0-9])|EC[1-9][0-9])( [0-9][ABD-HJLNP-UW-Z]{2})?)$

这个模式允许使用3或4位和6或7位邮政编码(因此只有3或4位的外向代码,或带有6或7位数字的完整邮政编码),但它不允许点4和6(省略空格的邮政编码)。

我还有这个模式:

^(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,1}[0-9][ABD-HJLNP-UW-Z]{2})$

这个模式允许6或7位邮政编码,有或没有空格,但不支持不完整的邮政编码(只有外部编码)

很抱歉问一个已经在此处广泛涵盖的问题,但我找到的所有示例都符合我的要求的一部分,但并非全部。

理想情况下,我希望使用正则表达式模式来允许3、4、6和7位邮政编码,有或没有空格。

更新:

我重新做了我的测试用例,因为我认为最初并不是完全全面的。基本概念是应该遵循英国邮政编码模式,并验证以下任何组合:

1 Letter 1 Number
1 Letter 2 Numbers
2 Letters 1 Number
2 Letters 1 Number 1 Letter
2 Letters 2 Numbers
1 Letter 1 Number (OptionalSpace) 1 Number 2 Letters
1 Letter 2 Numbers (OptionalSpace) 1 Number 2 Letters
2 Letters 1 Number (OptionalSpace) 1 Number 2 Letters
2 Letters 1 Number 1 Letter (OptionalSpace) 1 Number 2 Letters
2 Letters 2 Numbers (OptionalSpace) 1 Number 2 Letters

希望以上内容能够清晰详尽,尽管有些难以阅读。

回答:

现在我已经拥有了一个正则表达式,可以通过以上所有情况(示例和模式)。如下评论所述,要想适应所有英国邮编几乎是不可能的,但是以下正则表达式满足我的需求,并且适用于90%的输入情况:

^(GIR 0AA)|[a-z-[qvx]](?:\d|\d{2}|[a-z-[qvx]]\d|[a-z-[qvx]]\d[a-z-[qvx]]|[a-z-[qvx]]\d{2})(?:\s?\d[a-z-[qvx]]{2})?$

看看这个问题和它的答案,获取一些灵感。此外,不要过于担心空格,你可以将它们去掉以简化过程! - HamZa
啊,我明白了,问题在于上面的只允许带空格的邮政编码。如果情况相反,我肯定会去掉任何带空格的编码。但是对于没有空格的编码来说,确定空格应该放在哪里就有点困难了。不过还是谢谢你! :) - JustinMoser
1
任何尝试这样做都注定会失败。没有正则表达式可以验证英国邮政编码,而且有许多特殊情况,例如Girobank、GIR 0AA和海外领土,整个BFPO都是如此,尽管现在正在改变。同样,许多国家使用相同的格式,这可能会导致验证方面的巨大问题。最简单的方法是创建一个查找表,其中包含一些官方数据,例如code point open:http://www.ordnancesurvey.co.uk/oswebsite/products/code-point-open。 - Ben
@Ben 谢谢你的建议。是的,我认为你是对的。我有一个正则表达式模式可以满足上面所有模式/示例,但在你提到的地方(GiroBank)仍然不够。幸运的是,它不是一个国际网站,只要它能验证上面的示例,就应该没问题。我会把我有的发出来。 - JustinMoser
1
我已经将我的评论扩展为答案,回应了@Justin的问题。也许我能帮助到某些人 :-). - Ben
@JustinMoser 我和您的需求几乎一样,但我还需要提取出和入(可选)代码,以便我可以将它们与中间的空格重新组合,并针对数据库进行搜索。基本上解析用户输入的搜索项。我选择了这个:(?<out>[A-Z]{1,2}(\d(?=\ ?\d[A-Z])|\d\d|\d[A-Z]?))\ ?(?<in>\d[A-Z]{0,2})? - DigitalDan
1个回答

7

你有注意到相关问题 英国邮编正则表达式(全面版) 吗?

英国政府提供的正则表达式是:

(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-HJKSTUW])|([A-Z-[QVX]][A-Z-[IJZ]][0-9][ABEHMNPRVWXY])))) [0-9][A-Z-[CIKMOV]]{2})

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


标记为答案的正则表达式只允许输入完整的邮编或不带空格的邮政编码。例如"SW11 9PT"可以验证,但"SW12"、"CR5"、"SW129PT"或"CR52EP"都不能。该答案的评论解决了空格问题,但仍然不允许只有3或4位数字的外向代码。我在发布之前看到了那个答案,但是没有一个建议能够解决所有问题,正如问题所述。无论如何,谢谢 :) - JustinMoser
我已经尝试了该页面上的每个正则表达式,但没有一个完全有效。只有包含字母和数字的3位或4位外部邮编以及带或不带空格的6位或7位完整邮编应该被验证。我不介意它是否是一个有效的邮编,在事后我可以进行手动检查,我只需要确保它能够识别输入的是邮编而不是城镇/地区名称。 - JustinMoser
根据您提供的问题和维基百科,我觉得您的正则表达式不正确:“只有当结构以A9A开头时,第三个位置才会出现字母ABCDEFGHJKPSTUW。”在您的答案中,缺少了字母P! - LeBaptiste
@leBap,你可能已经注意到了,我的回答已经有3.5年的时间了。所以我的回答可能已经过时了。我会在找到一些空闲时间后进行检查和更新。 - rekire
@rekire,我注意到这是一篇旧帖子,但由于这个答案仍然被很多人查看,我想强调一下这个小差异,以防万一有人使用了你的正则表达式,当然这并不是批评。请注意,英国政府资源中有一些邮政编码格式比维基百科介绍的规则更宽松:https://www.gov.uk/government/uploads/system/uploads/attachment_data/file/488478/Bulk_Data_Transfer_-_additional_validation_valid_from_12_November_2015.pdf - LeBaptiste

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接