Working on a site which asks users to enter a “place name, area or postcode” to search by, niggly problem where searching for postcode “OX2” for example, not only returned properties in OX2, but also in OX29.
To solve this I added 2 functions, each with a RegEx check, one to check if the query string was a valid UK postcode, the second to check if it was the first part of a UK postcode.
function is_full_postcode($postcode)
{
return preg_match('/^(([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2}))$/ui', $postcode);
}
function is_partial_postcode($postcode)
{
return preg_match('/^(([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]))))))$/', $postcode);
}
I then checked against these results when building the MySql query:
if($fullPostcode === 1){
$location_where .= "{$location_col}
= '{$location}'{$location_join}";
}
else if($partialPostcode === 1){
$location_where .= "{$location_col}
LIKE '{$location} %'{$location_join}";
} else{
$location_where .= "{$location_col}
LIKE '%{$location}%'{$location_join}";
}
Thanks to MGBrown for the initial postcode regEx.