I need to validate a Canadian postal code (for example, M4B 1C7
) using C# (.NET) regular expressions.
Asked
Active
Viewed 6.0k times
64

Alan Moore
- 73,866
- 12
- 100
- 156

Jimmy
- 2,106
- 12
- 39
- 53
7 Answers
106
Canadian postal codes can't contain the letters D, F, I, O, Q, or U, and cannot start with W or Z:
[ABCEGHJKLMNPRSTVXY][0-9][ABCEGHJKLMNPRSTVWXYZ][0-9][ABCEGHJKLMNPRSTVWXYZ][0-9]
If you want an optional space in the middle:
[ABCEGHJKLMNPRSTVXY][0-9][ABCEGHJKLMNPRSTVWXYZ] ?[0-9][ABCEGHJKLMNPRSTVWXYZ][0-9]

Gordon Gustafson
- 40,133
- 25
- 115
- 157
-
6+1 for "Canadian postal codes can't have certain letters". You might want to also add that the leading letter is more restricted, then the second and third. – Richard McGuire Jul 18 '09 at 04:03
-
thanks a ton for answer...this works fine for codes like M4B1E8 ...but it wont work for M4B 1E8. Canada postal could have space after 3 characters..reference here:http://www.mongabay.com/igapo/toronto_zip_codes.htm – Jimmy Jul 18 '09 at 21:57
-
8Ideally, you should ignore whitespace on input and normalise the data to a canonical format for storage. That way, people can enter postal codes with or without spaces, and it won't matter. You can format them for output purposes if needed. – Rob Jul 19 '09 at 01:21
-
2There shouldn't be an F in the first sequence, you can check here: http://www.infinitegravity.ca/postalcodeformat.htm to verify – Tilendor Mar 08 '10 at 18:17
-
1If you want the space to be optional, put a question mark after it. – GalacticCowboy Jun 08 '10 at 17:18
-
The letter 'F' is not used in Canadian postal codes. Also, your second regexp contains an extra 'U' at the end (typo!) – ItalyPaleAle Jan 28 '15 at 19:33
-
Note, these regexs do not take in account of trailing or leading characters; nor, will it check length. If this important to you, you should prepend "^" and append "$" to the regexs in order to the assert that from the starting to the ending of the string to be match is a valid postal code. Example: `^[ABCEGHJKLMNPRSTVXY][0-9][ABCEGHJKLMNPRSTVWXYZ] ?[0-9][ABCEGHJKLMNPRSTVWXYZ][0-9]$` – Tyler Oct 18 '17 at 17:01
-
^[ABCEGHJ-NPRSTVXY]{1}[0-9]{1}[ABCEGHJ-NPRSTV-Z]{1}[ ]?[0-9]{1}[ABCEGHJ-NPRSTV-Z]{1}[0-9]{1}$ – koo9 Nov 24 '17 at 19:49
5
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]

user3111634
- 81
- 1
- 1
2
I suggest the following:
bool FoundMatch = false;
try {
FoundMatch = Regex.IsMatch(SubjectString, "\\A[ABCEGHJKLMNPRSTVXY]\\d[A-Z] ?\\d[A-Z]\\d\\z");
} catch (ArgumentException ex) {
// Syntax error in the regular expression
}

Templar
- 5,067
- 7
- 34
- 39
-
I've modified my answer to exclude invalid letters in the first character, as per http://www.infinitegravity.ca/postalcodeformat.htm. – Templar Jul 18 '09 at 16:17
-
3f you don't want to have to do two slashes for every slash, use an @ string literal as in `@"\A[ABCEGHJKLMNPRSTVXY]\d[A-Z] ?\d[A-Z]\d\z"`. – cdmckay Jul 19 '09 at 01:27
1
Try this:
function postalCodeCheck (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;
}

mmadush
- 57
- 4
-1
Validating the format of a postal code without validating its meaning isn't worth it, since typos can still result in a valid postal code for the wrong address. You want to validate the code against the address database. See http://www.canadapost.ca/cpo/mc/business/productsservices/atoz/postalcodeproducts.jsf

joe snyder
- 3,629
- 2
- 21
- 13
-
-
https://www.canadapost.ca/pca/ is a link to the start of the can post validation feature. Great tool, free trial. – ransems Mar 17 '20 at 13:52
-4
class Program
{
static void Main(string[] args)
{
string c1;
string c2;
string c3;
string c4;
string c5;
string c6;
string c7;
int sortie;
bool parfais = true;
Console.WriteLine("entrer votre code postal");
string cp = Console.ReadLine();
if (cp.Length == 7)
{
c1 = cp.Substring(0, 1);
c2 = cp.Substring(1, 1);
c3 = cp.Substring(2, 1);
c4 = cp.Substring(3, 1);
c5 = cp.Substring(4, 1);
c6 = cp.Substring(5, 1);
c7 = cp.Substring(6, 1);
if (int.TryParse(c1, out sortie))
{
parfais = false;
Console.WriteLine("le 1er caratere doit etre une lettre");
}
if (int.TryParse(c2, out sortie) == false)
{
parfais = false;
Console.WriteLine("le 2e caratere doit etre un nombre");
}
if (int.TryParse(c3, out sortie))
{
parfais = false;
Console.WriteLine("le 3e caratere doit etre une lettre");
}
if (c4.Contains(" ") == false)
{
parfais = false;
Console.WriteLine("vous devez utiliser un espace");
}
if (int.TryParse(c5, out sortie) == false)
{
parfais = false;
Console.WriteLine("le 5e caratere doit etre un nombre");
}
if (int.TryParse(c6, out sortie))
{
parfais = false;
Console.WriteLine("le 6e caratere doit etre une lettre");
}
if (int.TryParse(c7, out sortie) == false)
{
parfais = false;
Console.WriteLine("le 7e caratere doit etre un nombre");
}
else if(parfais == true)
{
Console.WriteLine("code postal accepter");
Console.ReadLine();
}
}
else
{
Console.WriteLine("le code postal doit contenir 7 caratere incluant l'espace");
}
Console.ReadLine();
-
1The OP wants to use regular expressions. There aren't any in this answer. – Erick G. Hagstrom Nov 13 '15 at 22:45