If you use regular expressions to match British postal codes (part or whole), you are doing it wrong. Also, note that before you go any further, no matter how you write your code, there is one case where the format will be ambiguous: BS22 may well belong to BS2 2AB or BS22 5GS. There is absolutely no way to tell, and you will need to make a decision based on this.
The proposed algorithm considers the case of BS22 as BS22. It looks like this:
<?php function testPostcode($mypostcode) { if (($posOfSpace = stripos($mypostcode," ")) !== false) return substr($mypostcode,0,$posOfSpace); // Deal with the format BS000 if (strlen($mypostcode) < 5) return $mypostcode; $shortened = substr($mypostcode,0,5); if ((string)(int)substr($shortened,4,1) === (string)substr($shortened,4,1)) { // BS000. Strip one and return return substr($shortened,0,4); } else { if ((string)(int)substr($shortened,3,1) === (string)substr($shortened,3,1)) { return substr($shortened,0,3); } else return substr($shortened,0,2); } } // Test cases $postcodes = array("BS3 3PL", "BS28BS","BS34","BS345","BS32EQ"); foreach ($postcodes as $k => $v) { echo "<p>".$v." => ".testPostcode($v)."</p>"; }
It is faster and easier to maintain than regular expression.
source share