Efficient regex for Canadian postal code function

Solution 1:

User kind, postal code strict, most efficient format:

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

Allows:

  • h2t-1b8
  • h2z 1b8
  • H2Z1B8

Disallows:

  • Z2T 1B8 (leading Z)
  • H2T 1O3 (contains O)

Leading Z,W or to contain D, F, I, O, Q or U

Solution 2:

Add anchors to your pattern:

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

^ means "start of string" and $ means "end of string". Adding these anchors will prevent the C from slipping in to the match since your pattern will now expect a whole string to consist of 6 (sometimes 7--as a space) characters. This added bonus should now alleviate you of having to subsequently check the string length.

Also, since it appears that you want to allow hyphens, you can slip that into an optional character class that includes the space you were originally using. Be sure to leave the hyphen as either the very first or very last character; otherwise, you will need to escape it (using a leading backslash) to prevent the regex engine from interpreting it as part of a character range (e.g. A-Z).

Solution 3:

This one handles us and ca codes.

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 '));

Solution 4:

You have a problem with the regex StatsCan has posted the rules for what is a valid Canadian postal code:

The postal code is a six-character code defined and maintained by Canada Post Corporation (CPC) for the purpose of sorting and delivering mail. The characters are arranged in the form ‘ANA NAN’, where ‘A’ represents an alphabetic character and ‘N’ represents a numeric character (e.g., K1A 0T6). The postal code uses 18 alphabetic characters and 10 numeric characters. Postal codes do not include the letters D, F, I, O, Q or U, and the first position also does not make use of the letters W or Z.

The regex should be if you wanted it strict.

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

Also \d means number not necessarily 0-9 there may be the one errant browser that treats it as any number in unicode space which would likely cause issues for you downstream.

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