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

匹配

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

不匹配

aWC2H 7LT WC2H 7LTa WC2H

我怎么解决这个问题?


当前回答

我们得到了一个说明:

UK postcodes must be in one of the following forms (with one exception, see below): 
    § A9 9AA 
    § A99 9AA
    § AA9 9AA
    § AA99 9AA
    § A9A 9AA
    § AA9A 9AA
where A represents an alphabetic character and 9 represents a numeric character.
Additional rules apply to alphabetic characters, as follows:
    § The character in position 1 may not be Q, V or X
    § The character in position 2 may not be I, J or Z
    § The character in position 3 may not be I, L, M, N, O, P, Q, R, V, X, Y or Z
    § The character in position 4 may not be C, D, F, G, I, J, K, L, O, Q, S, T, U or Z
    § The characters in the rightmost two positions may not be C, I, K, M, O or V
The one exception that does not follow these general rules is the postcode "GIR 0AA", which is a special valid postcode.

我们想出了这个:

/^([A-PR-UWYZ][A-HK-Y0-9](?:[A-HJKS-UW0-9][ABEHMNPRV-Y0-9]?)?\s*[0-9][ABD-HJLNP-UW-Z]{2}|GIR\s*0AA)$/i

但是注意-这允许组之间有任意数量的空格。

其他回答

我一直在寻找一个英国邮政编码正则表达式的最后一天左右,无意中发现了这个线程。我尝试了上面的大部分建议,但没有一个对我有用,所以我想出了自己的正则表达式,据我所知,它捕获了截至1月13日的所有有效的英国邮政编码(根据皇家邮政的最新文献)。

The regex and some simple postcode checking PHP code is posted below. NOTE:- It allows for lower or uppercase postcodes and the GIR 0AA anomaly but to deal with the, more than likely, presence of a space in the middle of an entered postcode it also makes use of a simple str_replace to remove the space before testing against the regex. Any discrepancies beyond that and the Royal Mail themselves don't even mention them in their literature (see http://www.royalmail.com/sites/default/files/docs/pdf/programmers_guide_edition_7_v5.pdf and start reading from page 17)!

注意:在皇家邮政自己的文献中(链接以上),第3和第4位的位置略有模糊,如果这些字符是字母,则例外。我直接联系了皇家邮政,用他们自己的话说,“AANA 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>";

    }

?>

我希望它能帮助其他遇到这条线索寻找解决方案的人。

看起来我们将使用^(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-PR-UWYZ]([A-HK-Y][0-9]([0-9]|[ABEHMNPRV-Y])?|[0-9]([0-9]|[A-HJKPSTUW])?) ?[0-9][ABD-HJLNP-UW-Z]{2})

它假定邮政编码已转换为大写,并且没有前导字符或尾随字符,但在出码和入码之间接受可选空格。

特殊的“GIR0 0AA”邮政编码被排除在外,并且不会生效,因为它不在官方邮局的邮政编码列表中,据我所知,它不会被用作注册地址。如果需要,作为特殊情况添加它应该是微不足道的。

下面是一个基于链接到marcj答案的文档中指定格式的正则表达式:

/^[A-Z]{1,2}[0-9][0-9A-Z]? ?[0-9][A-Z]{2}$/

这和规格之间的唯一区别是,根据规格,最后两个字符不能在[CIKMOV]中。

编辑: 下面是另一个测试末尾字符限制的版本。

/^[A-Z]{1,2}[0-9][0-9A-Z]? ?[0-9][A-BD-HJLNP-UW-Z]{2}$/

下面的方法将检查邮政编码并提供完整的信息

const isValidUKPostcode = postcode => {
    try {
        postcode = postcode.replace(/\s/g, "");
        const fromat = postcode
            .toUpperCase()
            .match(/^([A-Z]{1,2}\d{1,2}[A-Z]?)\s*(\d[A-Z]{2})$/);
        const finalValue = `${fromat[1]} ${fromat[2]}`;
        const 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})|(([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})$/i;
        return {
            isValid: regex.test(postcode),
            formatedPostCode: finalValue,
            error: false,
            message: 'It is a valid postcode'
        };
    } catch (error) {
        return { error: true , message: 'Invalid postcode'};
    }
};
console.log(isValidUKPostcode('GU348RR'))
{isValid: true, formattedPostcode: "GU34 8RR", error: false, message: "It is a valid postcode"}
console.log(isValidUKPostcode('sdasd4746asd'))
{error: true, message: "Invalid postcode!"}
valid_postcode('787898523')
result => {error: true, message: "Invalid postcode"}