Kie*_*ton 171 regex validation postal-code regex-group
我正在使用正则表达式,它将仅在输入字符串中验证完整复杂的英国邮政编码.所有不常见的邮政编码表格都必须与通常一样.例如:
火柴
没有比赛
是否有任何官方甚至半官方的正则表达式用于此类事情?有关格式化和存储在数据库中的任何其他建议吗?
mar*_*rcj 187
我建议看一下英国政府数据标准的邮政编码[现已链接死亡; XML存档,请参阅维基百科进行讨论].有关于数据的简要描述,附加的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})
Run Code Online (Sandbox Code Playgroud)
正如维基百科的讨论所指出的那样,这将允许一些非真实的邮政编码(例如那些以AA,ZY开头)并且它们确实提供了一个你可以尝试的更严格的测试.
Col*_*lin 81
看起来我们将要使用^(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}))$
Run Code Online (Sandbox Code Playgroud)
这使空格可选,但确实将您限制为一个空格(将'&'替换为'{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}))$
Run Code Online (Sandbox Code Playgroud)
这不包括海外领土,只强制执行格式,而不是存在不同的区域.它基于以下规则:
可以接受以下格式:
哪里:
最好的祝愿
科林
ctw*_*els 45
我最近发布了一个答案,以在英国的邮政编码为R语言这个问题.我发现英国政府的正则表达式模式不正确,无法正确验证某些邮政编码.不幸的是,这里的许多答案都是基于这种不正确的模式.
我将在下面概述其中一些问题,并提供一个实际有效的修订正则表达式.
我的答案(和一般的正则表达式):
如果您不关心坏的正则表达式并且只想跳到答案,请向下滚动到" 答案"部分.
不应使用本节中的正则表达式.
这是英国政府为开发人员提供的失败的正则表达式(不确定此链接将会持续多长时间,但您可以在他们的批量数据传输文档中看到它):
^([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})$
Run Code Online (Sandbox Code Playgroud)
正如许多开发人员可能做的那样,他们复制/粘贴代码(特别是正则表达式)并粘贴它们以期望它们起作用.虽然这在理论上很好,但在这种特殊情况下却失败了,因为从这个文档中复制/粘贴实际上将一个字符(空格)更改为换行符,如下所示:
^([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})$
Run Code Online (Sandbox Code Playgroud)
大多数开发人员要做的第一件事就是在不考虑两次的情况下擦除换行符.现在正则表达式将不匹配其中包含空格的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})$
^
Run Code Online (Sandbox Code Playgroud)
^([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})$
^^ ^ ^ ^^
Run Code Online (Sandbox Code Playgroud)
邮政编码正则表达式不正确地锚定了正则表达式.使用此正则表达式来验证邮政编码的任何人都可能会感到惊讶,如果像这样的值fooA11 1AA通过.那是因为他们已经锚定了第一个选项的开始和第二个选项的结束(彼此独立),正如上面的正则表达式所指出的那样.
这意味着^(在行的开头断言位置)仅适用于第一个选项([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})$
Run Code Online (Sandbox Code Playgroud)
要解决此问题,应将这两个选项包装在另一个组(或非捕获组)中,并将锚点放在其周围:
^(([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}))$
^^ ^^
Run Code Online (Sandbox Code Playgroud)
^([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})$
^^
Run Code Online (Sandbox Code Playgroud)
正则表达式缺少-此处以指示一系列字符.就目前而言,如果邮政编码的格式ANA NAA(A代表一个字母并N代表一个数字),并且它以除了A或之外的任何内容开头Z,它将失败.
这意味着它将匹配A1A 1AA和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})$
^
Run Code Online (Sandbox Code Playgroud)
^([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})$
^
Run Code Online (Sandbox Code Playgroud)
我发誓他们甚至在网上公布之前都没有测试过这个东西.他们使错误的字符集可选.他们在[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})$
^
Run Code Online (Sandbox Code Playgroud)
这个正则表达式的表现极差.首先,他们放置了最不可能的模式选项,以便GIR 0AA在开始时匹配.与任何其他邮政编码相比,有多少用户可能拥有此邮政编码; 可能从未?这意味着每次使用正则表达式时,它必须首先耗尽此选项,然后再继续下一个选项.要查看性能如何受影响,请在翻转选项后检查原始正则表达式对相同正则表达式所采取的步数(35)(22).
性能的第二个问题是由于整个正则表达式的结构方式.如果一个选项失败,那么对每个选项都没有任何回溯.当前正则表达式的结构方式可以大大简化.我在" 答案"部分提供了相应的修复程序.
这本身可能不是一个问题,但它确实引起了大多数开发人员的关注.正则表达式中的空格不是可选的,这意味着输入邮政编码的用户必须在邮政编码中放置一个空格.这是一个简单的解决方法,只需?在空格后添加以使其可选.有关修复,请参阅" 答案"部分.
修复" 问题"部分中列出的所有问题并简化模式会产生以下更短,更简洁的模式.我们也可以删除大多数组,因为我们正在验证整个邮政编码(不是单个部分):
^([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})$
Run Code Online (Sandbox Code Playgroud)
通过从一种情况(大写或小写)中删除所有范围并使用不区分大小写的标记,可以进一步缩短这一点.注意:有些语言没有,所以请使用上面较长的语言.每种语言都以不同的方式实现大小写不敏感标记.
^([A-Z][A-HJ-Y]?[0-9][A-Z0-9]? ?[0-9][A-Z]{2}|GIR ?0A{2})$
Run Code Online (Sandbox Code Playgroud)
更短的更换再次[0-9]用\d(如果你的正则表达式引擎支持的话):
^([A-Z][A-HJ-Y]?\d[A-Z\d]? ?\d[A-Z]{2}|GIR ?0A{2})$
Run Code Online (Sandbox Code Playgroud)
在不确保特定字母字符的情况下,可以使用以下内容(请记住简化1.修复英国政府的正则表达式也已应用于此处):
^([A-Z]{1,2}\d[A-Z\d]? ?\d[A-Z]{2}|GIR ?0A{2})$
Run Code Online (Sandbox Code Playgroud)
如果你不关心特殊情况,甚至更进一步GIR 0AA:
^[A-Z]{1,2}\d[A-Z\d]? ?\d[A-Z]{2}$
Run Code Online (Sandbox Code Playgroud)
我不建议对邮政编码进行过度验证,因为新的区域,区域和分区可能会在任何时间点出现.我建议可能做的是增加对边缘案例的支持.本维基百科文章中列出了一些特殊情况.
这是复杂的正则表达式,包括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)$
Run Code Online (Sandbox Code Playgroud)
并且与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)$
Run Code Online (Sandbox Code Playgroud)
维基百科的文章目前陈述(某些格式略有简化):
AI-1111:安圭拉ASCN 1ZZ:阿森松岛STHL 1ZZ:圣赫勒拿TDCU 1ZZ:Tristan da CunhaBBND 1ZZ: 英属印度洋领地BIQQ 1ZZ:英属南极领土FIQQ 1ZZ: 福克兰群岛GX11 1ZZ:直布罗陀PCRN 1ZZ:皮特凯恩群岛SIQQ 1ZZ:南乔治亚岛和南桑威奇群岛TKCA 1ZZ: 特克斯和凯科斯群岛BFPO 11:Akrotiri和DhekeliaZZ 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)$
Run Code Online (Sandbox Code Playgroud)
虽然他们最近改变了它以更好地与英国邮政编码系统BF#(#代表一个数字)对齐,但它们被认为是可选的替代邮政编码.这些邮政编码遵循(ed)格式BFPO,后跟1-4位数字:
^BFPO ?\d{1,4}$
Run Code Online (Sandbox Code Playgroud)
圣诞老人的另一个特例(如其他答案中所述):SAN TA1是一个有效的邮政编码.正则表达式非常简单:
^SAN ?TA1$
Run Code Online (Sandbox Code Playgroud)
Ben*_*Ben 42
没有能够验证邮政编码的全面的英国邮政编码正则表达式.您可以使用正则表达式检查邮政编码是否格式正确; 并不是说它确实存在.
邮政编码是任意复杂的,不断变化的.例如W1,对于每个邮政编码区域,outcode 不会,也可能永远不会有1到99之间的每个数字.
你不能指望目前永远存在的是什么.例如,1990年,邮局决定阿伯丁变得有点拥挤.他们在AB1-5的末尾添加了0,使其成为AB10-50,然后在这些之间创建了许多邮政编码.
无论何时构建新街道,都会创建新的邮政编码.这是获得构建许可的过程的一部分; 地方当局有义务与邮局保持最新情况(并非他们都这样做).
此外,正如许多其他用户所指出的那样,有特殊的邮政编码,如Girobank,GIR 0AA,以及圣诞老人信件,SAN TA1 - 你可能不想在那里发布任何东西,但它似乎没有被任何其他答案覆盖.
然后,有BFPO邮政编码,现在改为更标准的格式.两种格式都有效.最后,有海外领土来源维基百科.
+----------+----------------------------------------------+ | 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 | +----------+----------------------------------------------+
接下来,您必须考虑到英国将其邮政编码系统"导出"到世界上许多地方.验证"英国"邮政编码的任何内容也将验证许多其他国家/地区的邮政编码.
如果您想验证英国邮政编码,最安全的方法是使用当前邮政编码的查找.有很多选择:
Ordnance Survey 根据开放数据许可证发布Code-Point Open.它将落后于时代,但它是免费的.这将(可能 - 我不记得)不包括北爱尔兰的数据,因为军械测量局没有在那里进行调查.北爱尔兰的地图由北爱尔兰的军械测量局进行,他们有单独的付费指针产品.您可以使用此功能并附加少量未轻易覆盖的内容.
皇家邮政发布邮政编码地址文件(PAF),其中包括我不确定Code-Point Open的BFPO.它定期更新,但需要花钱(有时它们可能是彻头彻尾的意思).PAF包含完整地址而不仅仅是邮政编码,并附带自己的程序员指南.开放数据用户组(ODUG)目前正在游说让PAF免费发布,以下是对其位置的描述.
最后,还有AddressBase.这是Ordnance Survey,地方当局,皇家邮政和匹配公司之间的合作,以创建关于所有英国地址的所有信息的最终目录(它们也相当成功).这是付费的,但如果您与地方当局,政府部门或政府服务部门合作,他们可以免费使用.除了包含的邮政编码之外,还有更多的信息.
Ric*_*ers 21
我看了上面的一些答案,我建议不要使用来自@ Dan的答案(c.2010年12月15日)的模式,因为它错误地将几乎0.4%的有效邮政编码标记为无效,而其他人没有.
Ordnance Survey提供名为Code Point Open的服务:
包含英国所有当前邮政编码单元的列表
我使用grep以下方法从这些数据中对照完整的邮政编码列表(2013年7月6日)运行上面的每个正则表达式:
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"
Run Code Online (Sandbox Code Playgroud)
总共有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%)
Run Code Online (Sandbox Code Playgroud)
'^(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
Run Code Online (Sandbox Code Playgroud)
'^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
Run Code Online (Sandbox Code Playgroud)
当然,这些结果只处理被错误标记为无效的有效邮政编码.所以:
'^.*$'
# => 0
Run Code Online (Sandbox Code Playgroud)
我没有说过哪种模式最适合过滤掉无效的邮政编码.
Dan*_*Dan 17
^([A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA)$
Run Code Online (Sandbox Code Playgroud)
正则表达式匹配有效的英国邮政编码.在英国邮政系统中,并非所有位置都使用所有字母(与车辆登记牌相同),并且有各种规则来管理这一点.这个正则表达式考虑了这些规则.规则细节:邮政编码的前半部分有效格式[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仅使用Position - Forth.Contraint - ABEHMNPRVWXY邮政编码的后半部分有效格式[0-9] [AZ] [AZ]例外位置 - 第二和第三.Contraint - 未使用CIKMOV
http://regexlib.com/REDetails.aspx?regexp_id=260
Jes*_*era 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})|(([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})$
Run Code Online (Sandbox Code Playgroud)
更新:Jamie Bull指出的更新的正则表达式.不确定这是我的错误复制还是政府正则表达式中的错误,链接现在已经关闭...
更新:正如ctwheels发现的,这个正则表达式适用于javascript正则表达式风格.看看他对pcre(php)风格的评论.
小智 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})$
Run Code Online (Sandbox Code Playgroud)
从:
该文件还解释了其背后的逻辑.但是,它有一个错误(粗体),也允许小写,虽然合法不常见,所以修改版本:
^(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})$
Run Code Online (Sandbox Code Playgroud)
这适用于以前版本没有的新伦敦邮政编码(例如W1D 5LH).
Ant*_*hon 12
根据这个维基百科表

这种模式涵盖了所有情况
(?:[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})
Run Code Online (Sandbox Code Playgroud)
在Android\Java上使用时,请使用\\ d
Ali*_*xel 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}
Run Code Online (Sandbox Code Playgroud)
and*_*dre 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})
Run Code Online (Sandbox Code Playgroud)
在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
Run Code Online (Sandbox Code Playgroud)
对我来说,这是在尽可能多的验证之间取得适当的平衡,同时适应未来的需求并且易于维护.
我一直在寻找最后一天左右的英国邮政编码正则表达式,并偶然发现了这个帖子.我按照上面的大部分建议进行了工作,但没有一个对我有用,所以我提出了自己的正则表达式,据我所知,截至2013年1月,所有有效的英国邮政编码都是根据皇家邮政).
正则表达式和一些简单的邮政编码检查PHP代码发布如下.注意: - 它允许使用较低或大写的邮政编码和GIR 0AA异常,但是为了处理输入的邮政编码中间空间的存在,它还使用简单的str_replace来删除测试前的空间反对正则表达式.除此之外的任何差异和皇家邮政本身甚至在他们的文献中都没有提到它们(参见http://www.royalmail.com/sites/default/files/docs/pdf/programmers_guide_edition_7_v5.pdf并从第17页开始阅读) !
注意:在皇家邮政自己的文献(上面的链接)中,如果这些字符是字母,则第3和第4个位置存在轻微的歧义,并且存在例外情况.我直接联系了皇家邮政,并用他们自己的话说明了"Award NAA格式的外向代码第4位的信件没有例外,第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>";
}
?>
Run Code Online (Sandbox Code Playgroud)
我希望它可以帮助遇到此线程的其他任何人寻找解决方案.
这是一个基于文档中指定的格式的正则表达式,它与marcj的答案相关联:
/^[A-Z]{1,2}[0-9][0-9A-Z]? ?[0-9][A-Z]{2}$/
Run Code Online (Sandbox Code Playgroud)
该规格与规格之间的唯一区别在于,根据规格,最后2个字符不能在[CIKMOV]中.
编辑:这是另一个测试尾随字符限制的版本.
/^[A-Z]{1,2}[0-9][0-9A-Z]? ?[0-9][A-BD-HJLNP-UW-Z]{2}$/
Run Code Online (Sandbox Code Playgroud)
小智 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})$
Run Code Online (Sandbox Code Playgroud)
似乎更准确一点,请参阅维基百科文章"英国的邮政编码".
请注意,此正则表达式只需要大写字符.
更大的问题是,您是否限制用户输入以仅允许实际存在的邮政编码,或者您是否只是试图阻止用户在表单字段中输入完整的垃圾.正确匹配每个可能的邮政编码,以及将来证明它,是一个更难的难题,除非你是HMRC,否则可能不值得.
我想要一个简单的正则表达式,可以允许太多,但不能拒绝有效的邮政编码。我去了这个(输入是一个剥离/修剪的字符串):
/^([a-z0-9]\s*){5,8}$/i
Run Code Online (Sandbox Code Playgroud)
这允许使用最短的邮政编码,例如“L1 8JQ”,以及最长的邮政编码,例如“OL14 5ET”。
因为它最多允许 8 个字符,所以如果没有空格,它也会允许不正确的 8 个字符邮政编码:“OL145ETX”。但同样,这是一个简单的正则表达式,因为当它足够好时。
虽然这里有很多答案,但我对其中任何一个都不满意。它们中的大多数只是被破坏了,或者太复杂了,或者只是被破坏了。
我查看了@ctwheels 的答案,发现它非常解释性且正确;我们必须为此感谢他。然而,对于如此简单的事情来说,对我来说再次有太多的“数据”。
幸运的是,我设法获得了一个仅包含英格兰超过 100 万个有效邮政编码的数据库,并制作了一个小型 PowerShell 脚本来测试和基准测试结果。
英国邮政编码规范:有效邮政编码格式。
这是“我的”正则表达式:
^([a-zA-Z]{1,2}[a-zA-Z\d]{1,2})\s(\d[a-zA-Z]{2})$
Run Code Online (Sandbox Code Playgroud)
简短、简单、甜蜜。即使是最没有经验的人也能明白发生了什么。
解释:
^ 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
Run Code Online (Sandbox Code Playgroud)
结果(检查邮政编码):
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
Run Code Online (Sandbox Code Playgroud)