动态邮编验证

7

我需要根据国家的不同,在特定格式下验证邮政编码。

例如:

$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]
  • 有时允许/包含 连字符

所以,以 澳大利亚 为例,以下内容应该验证通过:

  • 1245
  • 4791
  • 7415

等等...

以下内容应该失败:

  • a113
  • 18q5
  • 1s-s7

等等...

鉴于此,我正在尝试创建一个单一的函数,用于针对邮政编码的所有变化验证给定国家的邮政编码。如果邮政编码与至少一条规则匹配,则函数应返回 true ,如果没有匹配,则返回 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


2
在你的正则表达式中添加起始和结束锚点:preg_match("/^$validation_rule$/", $postcode) - cOle2
注意:为了清晰起见,您可能需要省略一些内容,并且需要替换 A - bansi
1个回答

0

OP的正则表达式没有正确工作,因为它没有考虑到行的开头和结尾。

如@cOle2所评论的,行

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

应该被更改为

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

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

大家好,我在发布这个回答时已经过去了5年,这样这个问题就不会再出现在未回答的问题搜索结果中了。 - pagliuca

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接