Efficient regex for Canadian postal code function

JavascriptRegex

Javascript Problem Overview


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;
}

The regex looks for the pattern A0A 1B1. true tests:

A0A 1B1

A0A-1B1

A0A1B1

A0A1B1C << problem child

so I added a check for "-" or " " and then a check for length.

Is there a regex, or more efficient method?

Javascript Solutions


Solution 1 - Javascript

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 - Javascript

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 - Javascript

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 - Javascript

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/

Solution 5 - Javascript

This is a function that will do everything for you in one shot. Accepts AAA BBB and AAABBB with or without space.

function go_postal(){
        let postal = $("#postal").val();
        var regex = /^[A-Za-z]\d[A-Za-z][ -]?\d[A-Za-z]\d$/;
        var pr = regex .test(postal);
        if(pr === true){
            //all good          
        } else {
            // not so much
        }
    }

Solution 6 - Javascript

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;
}

Solution 7 - Javascript

regex = new RegExp(/^[ABCEGHJ-NPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][-]?\d[ABCEGHJ-NPRSTV-Z]\d$/i);
if(regex.test(value))
    return true;
else
    return false;

This is a shorter version of the original problem, where value is any text value. Furthermore, there is no need to test for value length.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJasonView Question on Stackoverflow
Solution 1 - JavascriptDanView Answer on Stackoverflow
Solution 2 - JavascriptKenneth K.View Answer on Stackoverflow
Solution 3 - JavascriptlysdexiaView Answer on Stackoverflow
Solution 4 - JavascriptArchimedes TrajanoView Answer on Stackoverflow
Solution 5 - JavascriptMichael NellesView Answer on Stackoverflow
Solution 6 - JavascriptmmadushView Answer on Stackoverflow
Solution 7 - JavascriptAlexander GotfridView Answer on Stackoverflow