1

I need to split a UK postcode into two. I have some code that gets the first half but it doesn't cover everything (such as gir0aa). Does anyone have anything better that validates all UK postcodes then breaks it into the first and second half? Thanks.

function firstHalf($postcode) {
if(preg_match('/^(([A-PR-UW-Z]{1}[A-IK-Y]?)([0-9]?[A-HJKS-UW]?[ABEHMNPRVWXY]?|[0-9]?[0-9]?))\s?([0-9]{1}[ABD-HJLNP-UW-Z]{2})$/i',$postcode))
    return preg_replace('/^([A-Z]([A-Z]?\d(\d|[A-Z])?|\d[A-Z]?))\s*?(\d[A-Z][A-Z])$/i', '$1', $postcode);
}

will split ig62ts into ig6 or cm201ln into cm20.

Andy Lobel
  • 3,356
  • 9
  • 31
  • 40
  • 1
    Can you post example input and output data? – Colin Brock Feb 04 '12 at 21:15
  • You realise anything you generate to validate based on a regexp will likely be out of date in a few months.... to validate properly, you have to do a lookup... and for reference, the "two parts" are called the incode and the outcode – Mark Baker Feb 04 '12 at 21:19
  • Do you care about an actual validation or do you want just to break it into two peaces? – Cheery Feb 04 '12 at 21:27
  • well yea but i guess i could validate it against the database like mark baker said. still need to break it into 2 tho – Andy Lobel Feb 04 '12 at 21:37

2 Answers2

4

The incode is always a single digit followed by two alpha characters, so the easiest way to split is to chop off the last three characters, allowing it to be validated easily.

Trim any spaces: they're used purely for ease of human readability.

The first part that remains is then the outcode. This can be a single alpha character followed by 1 or 2 digits; two alpha characters followed by 1 or 2 digits; or one or two characters followed by a single digit, followed by an additional alpha character.

There are a couple of notable exceptions: SAN TA1 is a recognised postcode, as is GIR 0AA; but these are the only two that don't follow the standard pattern.

To test if a postcode is valid, a regexp isn't really adequate... you need to do a lookup to retrieve that information.

Mark Baker
  • 209,507
  • 32
  • 346
  • 385
  • nice about the last bit always being 3 characters so i can just do $outward = substr(0, -3, $postcode); and $inward = substr(-3, $postcode) which makes it easier – Andy Lobel Feb 09 '12 at 02:33
  • 2
    Yes, you can (at least if you get the arguments in the right order and ensure you get rid of extraneous spaces) $inCode = substr(trim($postcode), -3); $outCode = trim(substr(trim($postcode), 0, -3));.... it's surprisingly simple, and that will even work for postcodes like "SW1A 1AA". Then a lookup can test that the address actually exists. – Mark Baker Feb 09 '12 at 07:30
2

If you do not care about validation, based on information here (at the bottom of the page there are different regexps, including yours) http://en.wikipedia.org/wiki/Postcodes_in_the_United_Kingdom your can use for everything except of Anguilla

  $str = "BX3 2BB";
  preg_match('#^(.*)(\s+)?(\d\w{2})$#', $str, $matches);
  echo "Part #1 = " . $matches[1];
  echo "<br>Part #2 = " . $matches[3];
Cheery
  • 16,063
  • 42
  • 57