Validate Canadian Postal Code using regex

I have written a JavaScript to validate Canadian Postal Codes using regex.

However, it does not seem to be working:

JavaScript

If statement:

if (myform.zip.value == "" || myform.zip.value == null || myform.zip.value == "Postal Code" || myform.zip.value.length < 12 ) {
    alert("Please fill in field Postal Code. You should only enter 7 characters");
    myform.zip.focus();
    return false;
}

Function:

function okNumber(myform) {
  var regex = /^[ABCEGHJKLMNPRSTVXY]{1}\d{1}[A-Z]{1} *\d{1}[A-Z]{1}\d{1}$/;
  if (regex.test(myform.zip.value) == false) {
    alert("Input Valid Postal Code");
    myform.zip.focus();
    return false;
  }

  return true;
}

Problem

It doesn't work at all, although code is executing. When I run it, I get:

Please fill in field Postal Code. You should only enter 7 characters

An example valid postal code would be T2X 1V4.


Solution 1:

this will work for all canadian postal codes..

^[ABCEGHJKLMNPRSTVXY]{1}\d{1}[A-Z]{1} *\d{1}[A-Z]{1}\d{1}$

Solution 2:

A regex approach can validate the format of a Canadian postcode, but it's not sufficient to guarantee that the postcode actually exists.

For example: A9A 0A0 looks like a valid Canadian postcode, but the forward sortation area A9A doesn't actually exist.

Are you sure you wouldn't rather do some kind of lookup against an official list of postcodes?

Solution 3:

Here are the rules http://en.wikipedia.org/wiki/Postal_code#Reserved_characters

ABCEGHJKLMNPRSTVXY <-- letter used 
DFIOQU <-- letters not used because it mixes up the reader
WZ     <-- letters used but not in the first letter
With that in mind the following in the proper regex

@[ABCEGHJKLMNPRSTVXY][0-9][ABCEGHJKLMNPRSTVWXYZ][\s][0-9][ABCEGHJKLMNPRSTVWXYZ][0-9]

Solution 4:

The first error is the last condition in your initial if statement. myform.zip.value.length < 12 should always be true, so this part of your code will always alert the message "Please fill in field Postal Code. You should only enter 7 characters" and take focus back to the zip field. Since a valid postal code has a maximum of 7 characters, this should be changed to myform.zip.value.length > 7.

After making that correction, the postal code T2X 1V4 that you provided in the comments validates. However, the regular expression you used can be simplified (as was also mentioned in the comments). You can remove all instances of {1} since they're redundant. You probably also meant to follow the space with a ? instead of a *. A ? means that the previous character or expression can appear 0 or 1 time, while a * means that it can appear 0 or more times. I think you want at most one space in your postal codes.

Here's the full working code that I tested this with:

<!doctype html>
<html>
<head>
    <title>JavaScript Regex Tester</title>
    <meta charset="utf-8">
    <script>
        function validate(myform) {
            if (myform.zip.value == "" || myform.zip.value == null || myform.zip.value == "Postal Code" || myform.zip.value.length > 7 ) {
                alert("Please fill in field Postal Code. You should only enter 7 characters");
                myform.zip.focus();
                return false;
            }

            return okNumber(myform);
        }

        function okNumber(myform) {
            var regex = /^[ABCEGHJKLMNPRSTVXY]\d[A-Z] *\d[A-Z]\d$/;
            if (regex.test(myform.zip.value) == false) {
                alert("Input Valid Postal Code");
                myform.zip.focus();
                return false;
            }

            return true;
        }
    </script>
</head>
<body>
    <form action="#" name="myform" method="post">
        <input type="text" name="zip" value="Postal Code" />
        <input type="button" value="Submit" onclick="validate(document.myform);"/>
    </form>
</body>
</html>

One final note, usually when you see [A-Z] in a regular expression it's worth at least considering whether it should be [A-Za-z] to accept either upper or lower case letters. I don't know if this is the case for Canadian postal codes, but it usually is the case that most forms should accept either input and correct the case as needed.