1

Im not so good with regex. Im looking to add a validation function that will return true/false if the string entered into it is a valid US, UK, or CA zip/postal code.

US: NNNNN CA: LNL NLN UK: Lots of combinations

L = letter, N = Number

There are individual functions for US, and Canada, but I failed to come up with a single unified function to do this.

  • Do you want to do a *real* check for the UK (i.e. find only existing postcodes)? Or would a pattern be enough? – Pekka Nov 05 '10 at 00:02
  • 1
    Same question for US ... 66666 matches the pattern but is not a valid postal code. Then there's the `NNNNN-NNNN` "ZIP+4" form too. – Stephen P Nov 05 '10 at 00:14

2 Answers2

3

Take a look at Zend_Validate_Postcode from the Zend Framework:

Zend_Validate_PostCode allows you to determine if a given value is a valid postal code. Postal codes are specific to cities, and in some locales termed ZIP codes.

Zend_Validate_PostCode knows more than 160 different postal code formates. To select the correct format there are 2 ways. You can either use a fully qualified locale or you can set your own format manually.

I guess you could either look at the source, or use it as a stand-alone component. It may have dependencies within the ZF, but you will certainly not need to use the entire framework just for that component. Hope that helps.

karim79
  • 339,989
  • 67
  • 413
  • 406
2

My solution would be to go for three separate regexes using logical OR operators:

if (
    preg_match('/^\d{5}(?:\-\d{4})?$/i', $code, $matches) OR
    preg_match('/^[a-z]\d[a-z] ?\d[a-z]\d$/i', $code, $matches) OR
    preg_match('/^[a-z]{1,2}\d{1,2} ?\d[a-z]{2}$/i', $code, $matches)
) {
    // deal with $matches here
}

Note that this works because PHP uses short-circuit logic. Once one test has passed, the others are ignored so $matches won't be overridden.

lonesomeday
  • 233,373
  • 50
  • 316
  • 318