我有一个正则表达式,用于验证英国邮政编码,但现在我想提取代码的组成部分,我感到困惑。对于那些不知道英国邮政编码的例子的人是'WC1 1AA','WC11 1AA'和'M1 1AA'。
下面的正则表达式(格式化道歉)处理左侧和右侧部分之间缺少空格(这是\s{0,}
位)并且仍然有效(这很好)。
(?:(?:A[BL]|B[ABDHLNRST]?|C[ABFHMORTVW]|D[ADEGHLNTY]|E[CHNX]?|F[KY]|G[LUY]?|H[ADGPRSUX]|I[GMPV]|JE|K[ATWY]|L[ADELNSU]?|M[EKL]?|N[EGNPRW]?|O[LX]|P[AEHLOR]|R[GHM]|S[AEGKLMNOPRSTWY]?|T[ADFNQRSW]|UB|W[ACDFNRSV]?|YO|ZE)\d(?:\d|[A-Z])?\s{0,}\d[A-Z]{2})
我希望能够现在提取左侧和右侧,我知道括号用于此,但是已经有括号,并且正则表达式规范不容易阅读。所以我想这些括号需要更换,有人可以帮我修改括号吗?
我可以看到其他人会发现这个使用正则表达式,所以请随意使用它来验证英国邮政地址。
答案 0 :(得分:5)
实际上,括号用于提取,而不是括号。 (?:表达式中的结构是阻止括号执行提取的方式。您可能需要:
(?:((?:A[BL]|B[ABDHLNRST]?|C[ABFHMORTVW]|D[ADEGHLNTY]|E[CHNX]?|F[KY]|G[LUY]?|H[ADGPRSUX]|I[GMPV]|JE|K[ATWY]|L[ADELNSU]?|M[EKL]?|N[EGNPRW]?|O[LX]|P[AEHLOR]|R[GHM]|S[AEGKLMNOPRSTWY]?|T[ADFNQRSW]|UB|W[ACDFNRSV]?|YO|ZE)\d(?:\d|[A-Z])?)\s{0,}(\d[A-Z]{2}))
顺便说一下,我也会做出这样的改变:
(?:((?:A[BL]|B[ABDHLNRST]?|C[ABFHMORTVW]|D[ADEGHLNTY]|E[CHNX]?|F[KY]|G[LUY]?|H[ADGPRSUX]|I[GMPV]|JE|K[ATWY]|L[ADELNSU]?|M[EKL]?|N[EGNPRW]?|O[LX]|P[AEHLOR]|R[GHM]|S[AEGKLMNOPRSTWY]?|T[ADFNQRSW]|UB|W[ACDFNRSV]?|YO|ZE)\d(?:\d|[A-Z])?)\s*(\d[A-Z]{2}))
因为 \ s {0,} 是一种愚蠢的方式来写 \ s * 。
答案 1 :(得分:4)
此外,我建议不要试图彻底检查邮政编码。有效邮政编码列表可以更改,因此每次邮局更新PAF时都必须维护表达式。
你也错过了一些像BFPO,GIR,非地理邮政编码和海外领土这样的“特殊邮政编码”。有关您可能需要处理的内容的概述,请参阅wiki。
一般来说,对于大多数用途来说,“它看起来似乎有道理吗?”检查比试图完全确定它更好。没有什么比告诉客户他们不能使用您的服务更糟糕了,因为他们的地址不存在。
答案 2 :(得分:1)
在处理像这样的大型正则表达式时,你应该使用/x
选项(我认为在C#中称为RegexOptions.IgnorePatternWhitespace
)。 (?:)没有捕获,所以你需要做的就是将()
放在你想要的部分周围。 /x
选项的另一个好处是,您可以使用行尾注释(它们以#
开头)对正则表达式进行注释。您可能还需要注意\ d和\ s。它们可能匹配的次数超出预期(\s
匹配所有空格,而不仅仅是空格,至少在Perl 5.8及更高版本中,\d
匹配所有UNICODE数字字符,而不仅仅是[0-9]
)< / p>
Regex exp = new Regex(@"
(?:
( #capture first part
(?:
A[BL] | B[ABDHLNRST]? | C[ABFHMORTVW] |
D[ADEGHLNTY] | E[CHNX]? | F[KY] |
G[LUY]? | H[ADGPRSUX] | I[GMPV] |
JE | K[ATWY] | L[ADELNSU]? |
M[EKL]? | N[EGNPRW]? | O[LX] |
P[AEHLOR] | R[GHM] | S[AEGKLMNOPRSTWY]? |
T[ADFNQRSW] | UB | W[ACDFNRSV]? |
YO | ZE
)
\d
(?:
\d | [A-Z]
)?
) #end capture of first part
\s{0,}
( #capture second part
\d[A-Z]{2}
) #end capture of second part
)",
RegexOptions.IgnorePatternWhitespace
);