动态邮政编码验证

时间:2014-07-17 16:24:11

标签: php postal-code

我需要根据每个国家/地区的特定格式验证邮政编码。

例如:

$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为例,它应该验证为:

  • 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。但它对$myPostcode = '1468a';

也会返回true

有没有人有办法通过固定规则进行动态邮政编码验证?


更新

这是如何解决的;使用Zend库中的正则表达式:http://pastebin.com/DBKhpkur

1 个答案:

答案 0 :(得分:0)

OP的正则表达式无法正常工作,因为它没有考虑行的开始和结束。

如@ cOle2所述,第

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

应更改为

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

此外,正如OP所做的编辑所述,另一个好的解决方案是使用Zend库中的正则表达式:http://pastebin.com/DBKhpkur