题 加拿大邮政编码功能的高效正则表达式


var regex = /[A-Za-z]\d[A-Za-z] ?\d[A-Za-z]\d/;
var match = regex.exec(value);
if (match){
    if ( (value.indexOf("-") !== -1 || value.indexOf(" ") !== -1 ) && value.length() == 7 ) {
        return true;
    } else if ( (value.indexOf("-") == -1 || value.indexOf(" ") == -1 ) && value.length() == 6 ) {
        return true;
    }
} else {
        return false;
}

正则表达式寻找模式A0A 1B1。 真实的测试:

A0A 1B1

A0A-1B1

A0A1B1

A0A1B1C <<问题孩子

所以我添加了一个“ - ”或“”的检查,然后检查长度。

有正则表达式,还是更有效的方法?


22
2018-04-02 21:17


起源




答案:


为您的模式添加锚点:

var regex = /^[A-Za-z]\d[A-Za-z][ -]?\d[A-Za-z]\d$/;

^ 意思是“字符串的开头”和 $ 意思是“字符串的结尾”。添加这些锚将阻止 C 从滑入到匹配,因为您的模式现在将期望整个字符串由6个(有时7个作为空格)字符组成。这个额外的奖励现在应该减轻您必须随后检查字符串长度。

此外,由于您似乎想要允许连字符,您可以将其放入包含您最初使用的空间的可选字符类中。务必将连字符留作第一个或最后一个字符;否则,您将需要将其转义(使用前导反斜杠)以防止正则表达式引擎将其解释为字符范围的一部分(例如, A-Z)。


28
2018-04-02 21:20



我会跳进来说他也可以使用 i 标志,以便不需要显式的大写/小写检查。 - Dave
+1非常整洁的正则表达式。 - jurgenreza
这将允许无效的加拿大邮政编码。邮政编码永远不会以可能被误认为数字的字符开头:I,O,Q,U,W,Z ......因此:/ ^ [ABCEGHJKLMNPRSTVXY] \ d [ - ]?\ d [A-Za-z] \ d $ /; - Ben A. Hilleli
有意思,但我想知道:如果邮政编码总是以字母开头,为什么会将上述任何字母与数字混淆? W会被混淆的数字是多少?我敢肯定这些是邮政服务的问题:) - Kenneth K.
/^[ABCEGHJ-NPRSTVXY][0-9][ABCEGHJ-NPRSTV-Z] [0-9][ABCEGHJ-NPRSTV-Z][0-9]$/ 是一个更严格的正则表达式 - Vincent D'amour


这个处理我们和ca代码。

function postalFilter (postalCode) {

    if (! postalCode) {
        return null;
    }

    postalCode = postalCode.toString().trim();

    var us = new RegExp("^\\d{5}(-{0,1}\\d{4})?$");
    var ca = new RegExp(/([ABCEGHJKLMNPRSTVXY]\d)([ABCEGHJKLMNPRSTVWXYZ]\d){2}/i);

    if (us.test(postalCode.toString())) {
        return postalCode;
    }

    if (ca.test(postalCode.toString().replace(/\W+/g, ''))) {
        return postalCode;
    }
    return null;
}

// these 5 return null
console.log(postalFilter('1a1 a1a'));
console.log(postalFilter('F1A AiA'));
console.log(postalFilter('A12345-6789'));
console.log(postalFilter('W1a1a1')); // no "w"
console.log(postalFilter('Z1a1a1')); // ... or "z" allowed in first position!

// these return canada postal less space
console.log(postalFilter('a1a 1a1'));
console.log(postalFilter('H0H 0H0'));

// these return unaltered
console.log(postalFilter('H0H0H0'));
console.log(postalFilter('a1a1a1'));
console.log(postalFilter('12345'));
console.log(postalFilter('12345-6789'));
console.log(postalFilter('123456789'));

// strip spaces
console.log(postalFilter(' 12345 '));

17
2017-11-06 20:28



这个答案比目前接受的答案更清晰,更准确,因为加拿大邮政编码总是省略字母D,F,I,O,Q和U. /([ABCEGHJKLMNPRSTVWXYZ]\d){3}/i但是,缺少一个条件是第一个字母不能是W或Z. en.wikipedia.org/wiki/... - Robert Penner
似乎为我工作,谢谢。 - Antoine
@RobertPenner是对的。我更正了加拿大代码的正则表达式。不过,我敢打赌美元有更好的办法。 - lysdexia


您有正则表达式的问题StatsCan已发布有效加拿大邮政编码的规则:

邮政编码是由六个字符的代码定义和维护的   加拿大邮政公司(CPC)的分拣和目的   发送邮件。字符以'ANA NAN'的形式排列,   其中'A'代表字母字符,'N'代表a   数字字符(例如,K1A 0T6)。邮政编码使用18个字母   字符和10个数字字符。邮政编码不包括   字母D,F,I,O,Q或U,第一个位置也没有   使用字母W或Z.

如果你想严格要求正则表达式。

/^[ABCEGHJ-NPRSTVXY][0-9][ABCEGHJ-NPRSTV-Z] [0-9][ABCEGHJ-NPRSTV-Z][0-9]$/

另外\ d表示数字不一定 0-9 可能有一个错误的浏览器将其视为unicode空间中的任何数字,这可能会导致下游问题。

从: https://trajano.net/2017/05/canadian-postal-code-validation/


9
2018-05-10 22:24





用户种类,邮政编码严格:

/^[ABCEGHJ-NPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ -]?\d[ABCEGHJ-NPRSTV-Z]\d$/i

允许:

  • H2T-1B8
  • h2z 1b8
  • H2Z1B8

禁止:

  • Z2T 1B8(领先Z)
  • H2T 1O3(含O)

引导Z,W或包含D,F,I,O,Q或U.


4
2017-10-15 23:26





function postalFilter (postalCode, type) {

    if (!postalCode) {
        return null;
    }

    postalCode = postalCode.toString().trim();

    var us = new RegExp("^\\d{5}(-{0,1}\\d{4})?$");
   // var ca  = new RegExp(/^((?!.*[DFIOQU])[A-VXY][0-9][A-Z])|(?!.*[DFIOQU])[A-VXY][0-9][A-Z]\ ?[0-9][A-Z][0-9]$/i);
    var ca = new RegExp(/^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ]( )?\d[ABCEGHJKLMNPRSTVWXYZ]\d$/i);

    if(type == "us"){
        if (us.test(postalCode.toString())) {
            console.log(postalCode);
            return postalCode;
        }
    }

    if(type == "ca")
    {
        if (ca.test(postalCode.toString())) {
            console.log(postalCode);
            return postalCode;
        }
    }

    return null;
}

-1
2018-03-24 13:47