我在一个正则表达式后,将验证一个完整的复杂的英国邮政编码只在输入字符串。所有不常见的邮政编码形式必须包括以及通常。例如:

匹配

CW3 9不锈钢 SE5 0EG SE50EG Se5 0eg WC2H 7LT

不匹配

aWC2H 7LT WC2H 7LTa WC2H

我怎么解决这个问题?


当前回答

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

^((([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})$)

如果有什么格式没有涵盖,请告诉我

其他回答

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

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

是否易于使用和实现 是短暂的 都跑得很快 相当容易维护(与完整的邮政编码列表相比) 仍然捕获大多数输入错误

但是正则表达式往往很难维护,特别是对于那些一开始就没有想到它的人来说。所以它一定是:

尽量简单易懂 相对未来的证明

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

对我来说,这是尽可能多地验证之间的正确平衡,与此同时,未来的验证和易于维护。

看起来我们将使用^(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}))$

这并不包括海外领土,只是强制执行格式,而不是不同地区的存在。它基于以下规则:

可接受以下格式:

“秋天” A9 9 zz A99 9 zz AB9 9 zz AB99 9 zz A9C 9 zz AD9E 9 zz

地点:

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之外的任何字母。

最好的祝愿

科林

根据维基百科的表格

这种模式适用于所有情况

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

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

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

(Ruby语法忽略大小写)

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

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

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

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