Regex Script - Zip Code

I am trying to figure out how to make a regex script that can be applied both client and server side....so a .net vb or c# solution that implements a regex script and a javascript...aspx version...

The zip code should validate against a "Canadian Zip Code".



Thanks in advance:)
A Canadian postal code is a string of six characters in the format X#X #X#, where X is a letter and "#" is a single digit, with a space separating the third and fourth characters. An example is K1A 0B1, which is for Canada Post's Ottawa headquarters. The postal code H0H 0H0 is reserved for letters to Santa Claus.

Open in new window

LVL 11
Robb HillSenior .Net DeveloperAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

szabogiCommented:
Here is JavaScript to test for US and Canada zips.  I'll post a C# method next.
//tests for 5-digit US zip, zip plus 4, and canadian postal code
function fcnIsValidZip(s)
{
	val = s.value.trim();
 
	usZip = new RegExp(/(^\d{5}$)|(^\d{5}-\d{4}$)/);
	caZip = new RegExp(/(^[A-Z][0-9][A-Z][0-9][A-Z][0-9]$)|(^[A-Z][0-9][A-Z].[0-9][A-Z][0-9]$)/); //matches V3A3N1 or V3A 3N1 or V3A.3N1
	
	if (usZip.test(val)) 
	{
		return true;
	}
	
	val = val.toUpperCase();
 
	if (caZip.test(val.toUpperCase()))
	{
		return true;
	}
	
	//zip fails validation
	return false;
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
szabogiCommented:
Here are C# methods to perform regex validation on US and Canada zips.
using System.Text.RegularExpressions;
 
//class declaration and constructor code removed
 
/// <summary>
/// Validates zip code is nnnnn or nnnnn-nnnn format
/// </summary>
/// <param name="zip"></param>
/// <returns></returns>
public bool IsUSZip(string zip) 
{
if (zip.Length == 5 || zip.Length == 10)
{
Regex e = new Regex(@"(^\d{5}$)|(^\d{5}-\d{4}$)");
if (e.IsMatch(zip))
    return true;
else
    return false;
}
else
{
//zip fails length check
return false;
}
}
 
/// <summary>
/// Validates Canadian Postal Code
/// </summary>
/// <param name="postalCode"></param>
/// <returns></returns>
public bool IsCanadianPostalCode(string postalCode) 
{
	Regex e = new Regex(@"[ABCEGHJKLMNPRSTVXY]\d[A-Z] \d[A-Z]\d");
	if( e.IsMatch(postalCode) ) 
		return true;
	else 
		return false;
}

Open in new window

0
Ivo StoykovCommented:
Hi robbhill


//====================
using System.Text.RegularExpressions;
 
    public static bool test( String zip )
    {
      Regex r = new Regex(@"\w\d\w\s\d\w\d");
      return (r.IsMatch(zip));
    }
//=================================
 
// client side (js)
<script>
 
function test(zip)  { return(zip.search(/^\w\d\w\s\d\w\d$/i) != -1); }
 
</script>

Open in new window

0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

Robb HillSenior .Net DeveloperAuthor Commented:
So for the client side solution...and the server side...I need the conditional logic...to be such that so long as it passes one of the tests..US or Canadian....that the test succeeds....So for example in the Javascript solution...how you make it return true...so long as one of the two matched.
0
Ivo StoykovCommented:
Hi
you've mentioned
The zip code should validate against a "Canadian Zip Code".
I'm not aware of US format. would you send a sample like your Canadian (i.e. X#X#...)
I
0
Robb HillSenior .Net DeveloperAuthor Commented:
The above code works for US format...see above...im just still working on the complete functionality of my application.
0
Robb HillSenior .Net DeveloperAuthor Commented:
So at this point here is my revised jscript version:



 
case "zip" : 
			var USrexp = /(^\d{5}$)|(^\d{5}-\d{4}$)/ ;
			var CArexp = /(^[A-Z][0-9][A-Z][0-9][A-Z][0-9]$)|(^[A-Z][0-9][A-Z].[0-9][A-Z][0-9]$)/;
			if(!(value == '') && !USrexp.test(value) && !CArexp.text(value)){
   				alert(display + " must be in US or Canadian Zip format. ex: either '00000','00000-0000' or 'V3A3N1','V3A 3N1','V3A.3N1'");
				return false;
			}
			break;		

Open in new window

0
szabogiCommented:
Here's your source code, modified to include a return of TRUE if the value passed in validates correctly against the regex.  I've added a line that trims whitespace from the input value, which is important -- as you don't want to validate against a string that has whitespace in front or behind it.  I also realized that I forgot to give you the code that adds the TRIM extended capability to the JavaScript.  It's all here below now.  Copy all of this and save it to a new text file that you save with a .JS extension.  Then, just call fcnValidate() in the appropriate event to enable the client-side functionality.
//Custom JavaScript Functions to Provide Extended Capabilities
String.prototype.trim=function(){
    return this.replace(/^\s*|\s*$/g,'');
}
 
 
function fcnValidate(s)
{
	value = s.value.trim();
 
	var USrexp = /(^\d{5}$)|(^\d{5}-\d{4}$)/ ;
	var CArexp = /(^[A-Z][0-9][A-Z][0-9][A-Z][0-9]$)|(^[A-Z][0-9][A-Z].[0-9][A-Z][0-9]$)/;
	if(!(value == '') && !USrexp.test(value) && !CArexp.text(value))
	{
		alert(value + " must be in US or Canadian Zip format. ex: either '00000','00000-0000' or 'V3A3N1','V3A 3N1','V3A.3N1'");
		return false;
	}
	else
	{
		return true;
	}
}

Open in new window

0
ddrudikCommented:
Aren't there more constraints on Canadian zip codes than what you mention in the question?

Consider the exclusions mentioned at this page:
http://www.dbsoftlab.com/index.php/Regular-Expressions-/Is-Canadian-Zip-Code.html

Also, no function short of connecting to a address/zip code database will validate a zip code for a given address, it just will validate the general format of all Canadian zip codes.
0
Robb HillSenior .Net DeveloperAuthor Commented:
yes...format is what im looking for....not that its an actual Vancouver for example zip code.
0
Robb HillSenior .Net DeveloperAuthor Commented:
Final question..and then thank you all for all this great help.

If I just wanted a single line REGEX statement that essentially stated both the US and the Canadian statements...conditionally..so if either statement was true the statement was true...but it still would test both..just in one line of REGEX code.  My reason in asking for this is I wanted to use this regex statement in the RegularExpressionValidator control.

So how would you say:

/(^\d{5}$)|(^\d{5}-\d{4}$)/             or     /(^[A-Z][0-9][A-Z][0-9][A-Z][0-9]$)|(^[A-Z][0-9][A-Z].[0-9][A-Z][0-9]$)/  
0
Robb HillSenior .Net DeveloperAuthor Commented:
it does not appear when using the validator that any of the pipe delimiters are acting as an or statement..only the first statement is getting executed which in this case is (^\d{5}$)
0
Robb HillSenior .Net DeveloperAuthor Commented:
This US regex works...what makes this one better or worse than the one suggested above?  and how would you add the canadian too it in one string.

ValidationExpression="^(\d{5}-\d{4}|\d{5}|\d{9})$|^([a-zA-Z]\d[a-zA-Z] \d[a-zA-Z]\d)$"
0
Robb HillSenior .Net DeveloperAuthor Commented:
If anyone would like to enhance this please do..but here is my solution and it seems to be working.

Thanks for all your help.
<asp:TextBox ID="TextBox_Zip" runat="server" Text='<%# Bind("Zip") %>' Width="200px" CssClass="textbox"
									MaxLength="10" onChange="zipStr= this.value;"/><asp:RequiredFieldValidator ID="RequiredFieldValidator_Zip"
										runat="server" ErrorMessage="'Zip' is a required field." Display="Dynamic" Text="*"
										ControlToValidate="TextBox_Zip"/>
										<asp:RegularExpressionValidator  id="RegZip" ControlToValidate="TextBox_Zip"   EnableClientScript="true"
										Text="*"  ErrorMessage="Please Enter a Valid US or Canadian Zip Code"  ValidationExpression="^(\d{5}-\d{4}|\d{5}|\d{9})$|^([a-zA-Z]\d[a-zA-Z] \d[a-zA-Z]\d)$|(^[A-Z][0-9][A-Z][0-9][A-Z][0-9]$)|(^[A-Z][0-9][A-Z].[0-9][A-Z][0-9]$)" runat="server" SetFocusOnError="True" />

Open in new window

0
szabogiCommented:
Here you go.  A working example is at http://www.gulfweb.org/test/zipvalidate.htm.  You can do a view source on zipvalidate.htm to see how I am accessing the javascript function.  The included javascript is at http://www.gulfweb.org/test/zipvalidate.js.  If you click that it should prompt to download.

I'll post the javascript source code for zipvalidate.js below as well.  This regex incorporates zip, zip+4, and common canadian postal code formats.  I've had to do radio contest sign up form validation for the past 3 years and these 3 purmutations of the canadian postal code formats are quite common (V3A3N1','V3A 3N1','V3A.3N1).
//Custom JavaScript Functions to Provide Extended Capabilities
String.prototype.trim=function(){
    return this.replace(/^\s*|\s*$/g,'');
}
 
 
function fcnValidate(s)
{
	val = s.value.trim();
 
	var RegEx = /(^\d{5}$)|(^\d{5}-\d{4}$)|(^[A-Z][0-9][A-Z][0-9][A-Z][0-9]$)|(^[A-Z][0-9][A-Z].[0-9][A-Z][0-9]$)/ ;
	if(!(val == '') && !RegEx.test(val))
	{
		alert(val + " must be in US or Canadian Zip format. ex: either '00000','00000-0000' or 'V3A3N1','V3A 3N1','V3A.3N1'");
		return false;
	}
	else
	{
		alert(val + " is a good US Zip OR Canadian Postal Code");
		return true;
	}
}

Open in new window

0
szabogiCommented:
The Regular expression to combine the US with Canadian testing is this:

(^\d{5}$)|(^\d{5}-\d{4}$)|(^[A-Z][0-9][A-Z][0-9][A-Z][0-9]$)|(^[A-Z][0-9][A-Z].[0-9][A-Z][0-9]$)

It tests for Zip+4, Zip, and the 3 permutations of the Canadian postal code format.
0
Robb HillSenior .Net DeveloperAuthor Commented:
^(\d{5}-\d{4}|\d{5}|\d{9})$|^([a-zA-Z]\d[a-zA-Z] \d[a-zA-Z]\d)$|(^[A-Z][0-9][A-Z][0-9][A-Z][0-9]$)|(^[A-Z][0-9][A-Z].[0-9][A-Z][0-9]$)

If the above works.....what is the difference with yours below?

(^\d{5}$)|(^\d{5}-\d{4}$)|(^[A-Z][0-9][A-Z][0-9][A-Z][0-9]$)|(^[A-Z][0-9][A-Z].[0-9][A-Z][0-9]$)

 
0
Robb HillSenior .Net DeveloperAuthor Commented:
Well yours works...im going with it..hehe
0
Robb HillSenior .Net DeveloperAuthor Commented:
Thanks to you all!!!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.