匹配
- CW3 9SS
- SE5 0EG
- SE50EG
- se5 0eg
- WC2H 7LT
不匹配
- aWC2H 7LT
- WC2H 7LTa
- WC2H
匹配
不匹配
邮政编码可能会发生变化,唯一验证邮政编码的真正方法是拥有完整的邮政编码列表,并查看其中是否存在。
但正则表达式非常有用,因为它们:
但是,正则表达式往往难以维护,特别是对于那些不是第一次创建它的人来说。因此,必须满足以下要求:
这意味着本答案中的大多数正则表达式都不够好。例如,我可以看到[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
对我来说,这是在尽可能验证的同时保证未来可靠性和易维护性之间找到的正确平衡。
我已经寻找英国邮编正则表达式一整天了,偶然发现了这个帖子。我试用了上面大部分建议的正则表达式,但都不适用于我,因此我自己想出了一个正则表达式,据我所知,它能够捕捉到所有有效的英国邮政编码(根据Royal Mail最新的文献,截止至2013年1月)。
下面是正则表达式和一些简单的邮政编码检查PHP代码。注意:它允许小写或大写的邮政编码以及GIR 0AA异常情况,但为了处理输入的邮政编码中很可能存在空格的情况,它还使用了一个简单的str_replace在测试正则表达式之前去除了空格。除此之外,任何差异,Royal Mail在他们的文献中甚至都没有提到它们(请参见http://www.royalmail.com/sites/default/files/docs/pdf/programmers_guide_edition_7_v5.pdf,从第17页开始阅读)!
注意:在Royal Mail自己的文献中(上面的链接),第三和第四位之间存在一些模糊性,以及如果这些字符是字母时所采取的例外情况。我直接联系了Royal Mail以澄清这一点,按照他们自己的话说,“带有格式AANA NAA的Outward Code中第4位的字母没有任何例外情况,而格式为ANA NAA的Outward Code中第3位例外情况仅适用于Outward Code的最后一个字母。”就是这样!
<?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>";
}
?>
我希望这篇文章能对其他遇到同样问题的人有所帮助。
以下是需要翻译的内容:
/^[A-Z]{1,2}[0-9][0-9A-Z]? ?[0-9][A-Z]{2}$/
/^[A-Z]{1,2}[0-9][0-9A-Z]? ?[0-9][A-BD-HJLNP-UW-Z]{2}$/
A-Z
更加复杂 - 根据字符的位置,Q
从不被允许,V
只是偶尔使用。 - Zhaph - Ben Duguid^(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})$
虽然这里有很多答案,但我对它们都不太满意。大多数答案要么是错误的,要么过于复杂,要么根本不能用。
我看了一下@ctwheels的回答,我发现他的回答非常详细和正确;我们必须感谢他。但是对于我来说,这对于如此简单的事情来说还是“数据”太多了。
幸运的是,我设法获得了一个仅包含英格兰境内超过一百万活动邮政编码的数据库,并编写了一个小型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
^([a-zA-Z]{1,2}[a-zA-Z\d]{1,2})\s?(\d[a-zA-Z]{2})$
- Jon Humphrey我需要一个简单的正则表达式,可以允许输入过多的内容,但不应拒绝一个有效的邮政编码。我选择了这个正则表达式(输入为去除空格的字符串):
/^([a-z0-9]\s*){5,8}$/i
基本规则:
^[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)$
已针对我们客户数据库进行测试,似乎非常准确。
我使用以下正则表达式,我已经测试过它针对所有有效的英国邮政编码。它基于推荐规则,但尽可能简洁,并且不使用任何特殊的语言特定的正则表达式规则。
([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})
以下是我们处理英国邮政编码问题的方法:
^([A-Za-z]{1,2}[0-9]{1,2}[A-Za-z]?[ ]?)([0-9]{1}[A-Za-z]{2})$
说明:
这可以涵盖大多数格式,然后我们使用数据库来验证邮政编码是否真实存在,这些数据由openpoint驱动 https://www.ordnancesurvey.co.uk/opendatadownload/products.html
希望这能有所帮助
AANNA NAA
,这是无效的。 - ctwheels如果您不想在验证后再在服务器端对其进行修剪,那么此选项允许两侧的空格和制表符为空。
^\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*$)