PHP Найдите первую часть почтового индекса в Великобритании, когда полный или часть может быть введена

Кто-то, пожалуйста, избавь меня от моих страданий и помоги мне решить эту проблему.

У меня есть окно поиска почтового индекса, которое позволяет людям вводить полные почтовые индексы (например, BS34 5GF) или почтовые коды частей (например, BS34).

Мой поиск в почтовом индексе требует только первой части почтового индекса, и я пытаюсь найти наиболее эффективный способ обрезки строки, чтобы иметь только первый раздел без явного указания формата, в который он введен.

Вот некоторые примеры кодов: B2 5GG, B22 5GG, BS22 5GG, B25GG, BS25GG, BS225GG, B2, BS2, BS22

Это показывает, сколько возможных вариантов может быть. Каков наилучший способ гарантировать, что я всегда получаю первую часть почтового индекса?

Режимы IMHO – это правильное решение проблемы.

Игнорируя теперь адрес BFPO, попробуйте:

if (preg_match("(([AZ]{1,2}[0-9]{1,2})($|[ 0-9]))", trim($postcode), $match)) { $region=$match[1]; } 

Если вы используете регулярные выражения для соответствия британским почтовым индексам (часть или целое), вы делаете это неправильно. Кроме того, обратите внимание, прежде чем идти дальше, независимо от того, как вы пишете свой код, есть один случай, когда формат будет неоднозначным: BS22 вполне может принадлежать BS2 2AB или BS22 5GS. Невозможно сказать, и вам нужно будет принять решение на основе этого.

Предлагаемый алгоритм рассматривает случай BS22 как BS22. Это выглядит так:

 <?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>"; } 

Это быстрее и проще поддерживать, чем регулярное выражение.

Как насчет того, если вы вытащили пробелы и проверили длину. Я думаю, что все почтовые индексы должны быть длиной не менее 5 символов.

Если почтовый индекс меньше 5 символов, возьмите все это как код области. Если оно больше 5 символов, удалите последние 3 символа и возьмите остаток в качестве кода зоны:

 function getPostCodeArea($pcode){ $pcode = str_replace(' ', '', $pcode); if(strlen($pcode) > 4){ if(is_numeric($pcode{strlen($pcode)-1})){ $pcode = substr($pcode, 0, 4); }else{ $pcode = substr($pcode, 0, strlen($pcode)-3); } return $pcode; }else{ return $pcode; } } 

Это сделало бы работу:

Примечание. Это упрощенное регулярное выражение для почтового индекса.

 function getOutwardPostcodePart($postcode) { $matches = array(); if (preg_match("/^([a-zA-Z]{1,2}[0-9][0-9A-Za-z]{0,1}) {0,1}([0-9][A-Za-z]{2}){0,1}$/", $postcode, $matches )) { return $matches[1]; } return false; } 

Я не думаю, что в любом случае можно справиться с маловероятной ситуацией, когда действительная внешняя часть почтового индекса вводится только с частичной внутренней частью.