Динамическая проверка почтового индекса

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

Например:

$postcode_validation = array
(
    'Australia'     => array('NNNN'),
    'Bahrain'       => array('NNN', 'NNNN'),
    'Netherlands'   => array('NNNN AA'),
    'United States' => array('NNNNN', 'NNNNN-NNNN', 'NNNNN-NNNNNN')
);

В каждой стране может быть столько вариантов формата почтового индекса, сколько они хотят; где:

  • N = число [0-9]
  • A = буквы [a-zA-Z]
  • и иногда разрешает/содержит дефисы

Итак, если мы возьмем, например, Australia, оно должно подтвердиться как true для:

  • 1245
  • 4791
  • 7415

и т.д...

и должен завершиться ошибкой:

  • a113
  • 18q5
  • 1s-s7

и т.д...

Учитывая это, я пытаюсь создать единую функцию, которую я могу использовать для проверки почтового индекса для данной страны по всем вариантам почтового индекса. функция должна return true, если почтовый индекс соответствует хотя бы одному правилу, и return false, если совпадений нет.

Итак, вот как я пытался это сделать (начиная с простого):

<?php

// mapping
$postcode_validation = array
(
    'Australia'     => array('NNNN'),
    'Bahrain'       => array('NNN', 'NNNN'),
    'Netherlands'   => array('NNNN AA'),
    'United States' => array('NNNNN', 'NNNNN-NNNN', 'NNNNN-NNNNNN')
);

// helper function
function isPostcodeValid($country, $postcode)
{
    // Load Mapping
    global $postcode_validation;

    // Init
    $is_valid = false;

    // Check If Country Exists
    if (!array_key_exists($country, $postcode_validation))
        return false;

    // Load Postcode Validation Rules
    $validation_rules = $postcode_validation[$country];

    // Iterate Through Rules And Check
    foreach ($validation_rules as $validation_rule)
    {
        // Replace N with \d for regex
        $validation_rule = str_replace('N', '\\d', $validation_rule);

        // Check If Postcode Matches Pattern
        if (preg_match("/$validation_rule/", $postcode)) {
            $is_valid = true;
            break;
        }
    }

    // Finished
    return $is_valid;
}

// Test
$myCountry = 'Australia';
$myPostcode = '1468';
var_dump(isPostcodeValid($myCountry, $myPostcode));

?>

Это похоже работает, возвращая true. Но он также возвращает true для $myPostcode = '1468a';

У кого-нибудь есть способ сделать эту динамическую проверку почтового индекса по фиксированным правилам?


Обновить

Вот как это было решено; с помощью регулярного выражения из библиотеки Zend: http://pastebin.com/DBKhpkur


person Latheesan    schedule 17.07.2014    source источник
comment
Добавьте начальные и конечные привязки к вашему регулярному выражению: preg_match("/^$validation_rule$/", $postcode)   -  person cOle2    schedule 17.07.2014
comment
Примечание: возможно, вы опустили для ясности, вам также необходимо заменить A.   -  person bansi    schedule 17.07.2014


Ответы (1)


Регулярное выражение OP работало неправильно, потому что не учитывало начало и конец строки.

Как прокомментировал @cOle2, строка

if (preg_match("/$validation_rule/", $postcode)) {

следует изменить на

if (preg_match("/^$validation_rule$/", $postcode)) {

Кроме того, как отмечено в редактировании OP, еще одним хорошим решением является использование регулярного выражения из библиотеки Zend: http://pastebin.com/DBKhpkur

person pagliuca    schedule 18.04.2019
comment
Ребята, я опубликовал этот ответ через 5 лет после ОП, чтобы этот вопрос, наконец, перестал появляться при поиске вопросов без ответов. - person pagliuca; 18.04.2019