Я пытаюсь получить первую часть почтового индекса в Великобритании из строки, в которой может быть только первая часть почтового индекса или полный почтовый индекс. Я изо всех сил пытаюсь заставить это работать. У меня это работает, если полный почтовый индекс вводится с помощью упреждающего просмотра, но я не могу сделать упреждающий просмотр опциональным, поэтому, если вводится только первая часть почтового индекса, он сопоставляется.
Мое регулярное выражение до сих пор ([A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]([0-9ABEHMNPRV-Y])?)|[0-9][A-HJKPS-UW])(?=( ?[0-9][ABD-HJLNP-UW-Z]{2})))
У меня есть несколько почтовых индексов, которые должны совпадать, и это результаты с использованием приведенного выше регулярного выражения:
A10EA - Should match and does
A1 - Should match but doesn't
A10 0EA - Should match and does
A10 - Should match but doesn't
BH18 1AE - Should match and does
BH18AE - Should match and does
EC1M 6HJ - Should match and does
EC1M - Should match but doesn't
Z10 2EV - Shouldn't match and doesn't
QE3 6DA - Shouldn't match but matches E3 6DA
Может кто-нибудь помочь мне решить эту проблему?
RegEx, из которого я работал, является официальным почтовым отделением:
/^(GIR ?0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]([0-9ABEHMNPRV-Y])?)|[0-9][A-HJKPS-UW]) ?[0-9][ABD-HJLNP-UW-Z]{2})$/i
Прежде чем кто-либо помечает это как дубликат PHP Найти первую часть почтового индекса в Великобритании, когда можно будет ввести полностью или частично, это не. Ответ на этот вопрос не работает, см. Мой комментарий к ответу.
Согласно эта вики-страница почтовый индекс всегда оканчивается на «цифру, букву», это будет шаблон регулярного выражения \d\w\w$
, Теперь мы знаем, как определить, к чему это приведет, мы просто хотим запечатлеть все остальное.
Шаблон как (\S*)\s*\d\w\w$
буду работать. Это захватит первую половину и гарантирует, что вы не получите последнюю ‘цифру буквенную часть. Он будет захватывать первую часть, получая все, что не является пробелами, то есть только буквы и цифры.
Чтобы полностью объяснить это, скобки ()
это то, что мы фиксируем. \S
говорит «любой не пробел, с \S*
быть всем, что мы можем получить. так (\S*)
захватывает все до символа пробела, но захватывает все, если пользователь не вводит один. Полное регулярное выражение, которое я предоставил, будет также пытаться захватить «любой пробел, одну цифру, две буквы, конец строки», который обеспечит AA999AA
делится на AA99
а также 9AA
,
Я также только что заметил, что ваш вопрос гласит, что у вас может не быть той второй части. Я думаю, что вы можете обойти это, проверив длину строки. Если вы обрежете пробел и длина не превышает 5 символов, у вас должна быть только первая часть, поэтому не нужно никаких регулярных выражений.
отказ это не будет работать для почтовых индексов Ангильи. Я думаю, что для поддержки их почтовых индексов (\ S *) \ s * (?: \ D \ w \ w | — \ d {4}) $ будет работать.
Я смотрел на это неправильно. Я хочу получить первую часть почтового индекса и удалить вторую часть, если она есть, так почему бы сначала не проверить почтовый индекс, а затем проверить его на наличие и удалить его, если необходимо.
Я уже проверяю почтовый индекс, это код, который у меня уже был:
$validate = Validation::factory(array('postcode' => $postcode));
$validate->rule('postcode', 'not_empty');
$validate->rule('postcode', 'regex', array(':value', '/^(GIR ?(0AA)?|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]([0-9ABEHMNPRV-Y])?)|[0-9][A-HJKPS-UW]) ?([0-9][ABD-HJLNP-UW-Z]{2})?)$/i'));
if ( ! $validate->check())
{
$postcode = '';
}
Итак, теперь я добавил в это после этого:
if ($postcode)
{
$short_postcode = $postcode;
// Check for an end section and then if present, remove it
if (preg_match('/ ?([0-9])[ABD-HJLNP-UW-Z]{2})$/i', $postcode, $match, PREG_OFFSET_CAPTURE))
{
$short_postcode = substr($postcode, 0, $match[0][1]);
}
}
и это оставляет мне только первую часть почтового индекса, что я и хотел. Это Eval.in показывает, что это работает для всех примеров в моем вопросе.