不使用正则表达式的英国(GB)邮政编码验证 [英] United Kingdom (GB) postal code validation without regex

查看:157
本文介绍了不使用正则表达式的英国(GB)邮政编码验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试了几种正则表达式,但有时仍然拒绝了一些有效的邮政编码.

I have tried several regexes and still some valid postal codes sometimes get rejected.

搜索互联网,维基百科和SO,我只能找到正则表达式验证解决方案.

Searching the internet, Wikipedia and SO, I could only find regex validation solutions.

是否存在不使用正则表达式的验证方法?我认为,使用任何一种语言,移植起来都很容易.

Is there a validation method which does not use regex? In any language, I guess it would be easy to port.

我认为最简单的方法是将其与邮政编码数据库进行比较,但这需要从可靠的来源进行定期维护和更新.

I supose the easiest would be to compare against a postal code database, yet that would need to be maintained and updated periodically from a reliable source.

为了帮助将来的访问者并使您免于发布更多正则表达式,以下是我已经测试过的正则表达式(截至2013-04-24),可在Code Point(

To help future visitors and keep you from posting any more regexes, here's a regex which I have tested (as of 2013-04-24) to work for all postal codes in Code Point (see @Mikkel Løkke's answer):

//PHP PCRE (it was on Wikipedia, it isn't there anymore; I might have modified it, don't remember).
$strPostalCode=preg_replace("/[\s]/", "", $strPostalCode);
$bValid=preg_match("/^(GIR 0AA)|(((A[BL]|B[ABDHLNRSTX]?|C[ABFHMORTVW]|D[ADEGHLNTY]|E[HNX]?|F[KY]|G[LUY]?|H[ADGPRSUX]|I[GMPV]|JE|K[ATWY]|L[ADELNSU]?|M[EKL]?|N[EGNPRW]?|O[LX]|P[AEHLOR]|R[GHM]|S[AEGKLMNOPRSTY]?|T[ADFNQRSW]|UB|W[ADFNRSV]|YO|ZE)[1-9]?[0-9]|((E|N|NW|SE|SW|W)1|EC[1-4]|WC[12])[A-HJKMNPR-Y]|(SW|W)([2-9]|[1-9][0-9])|EC[1-9][0-9])[0-9][ABD-HJLNP-UW-Z]{2})$/i", $strPostalCode);

推荐答案

我正在根据 wiki页面编写此答案. a>.

I'm writing this answer based on the wiki page.

在检查验证部分时,似乎有6种格式(A =字母和9 =位数):

When checking on the validation part, it seems that there are 6 type of formats (A = letter and 9 = digit):

AA9A 9AA                       AA9A9AA                   AA9A9AA
A9A 9AA     Removing space     A9A9AA       order it     AA999AA
A9 9AA    ------------------>  A99AA     ------------->  AA99AA
A99 9AA                        A999AA                    A9A9AA
AA9 9AA                        AA99AA                    A999AA
AA99 9AA                       AA999AA                   A99AA

我们可以看到,长度可能从5到7不等,我们必须考虑某些特殊情况如果我们愿意.

As we can see, the length may vary from 5 to 7 and we have to take in account some special cases if we want to.

因此,我们正在编码的函数必须执行以下操作:

So the function we are coding has to do the following:

  1. 删除空格并转换为大写(或小写).
  2. 检查输入是否为异常,如果输入为异常,则应返回 valid
  3. 检查输入的长度是否为4 < 长度< 8.
  4. 检查其是否为有效的邮政编码.
  1. Remove spaces and convert to uppercase (or lower case).
  2. Check if the input is an exception, if it is it should return valid
  3. Check if the input's length is 4 < length < 8.
  4. Check if it's a valid postcode.

最后一部分很棘手,但我们将其按长度分为3个部分,以进行概述:

The last part is tricky, but we will split it in 3 sections by length for some overview:

  1. 长度= 7: AA9A9AA AA999AA
  2. 长度= 6: AA99AA A9A9AA A999AA
  3. 长度= 5: A99AA
  1. Length = 7: AA9A9AA and AA999AA
  2. Length = 6: AA99AA, A9A9AA and A999AA
  3. Length = 5: A99AA

为此,我们将使用switch().从现在开始,只需要逐个字符地检查是正确的字母还是数字即可.

For this we will be using a switch(). From now on it's just a matter of checking character by character if it's a letter or a number on the right place.

因此,让我们看一下我们的PHP实现:

So let's take a look at our PHP implementation:

function check_uk_postcode($string){
    // Start config
    $valid_return_value = 'valid';
    $invalid_return_value = 'invalid';
    $exceptions = array('BS981TL', 'BX11LT', 'BX21LB', 'BX32BB', 'BX55AT', 'CF101BH', 'CF991NA', 'DE993GG', 'DH981BT', 'DH991NS', 'E161XL', 'E202AQ', 'E202BB', 'E202ST', 'E203BS', 'E203EL', 'E203ET', 'E203HB', 'E203HY', 'E981SN', 'E981ST', 'E981TT', 'EC2N2DB', 'EC4Y0HQ', 'EH991SP', 'G581SB', 'GIR0AA', 'IV212LR', 'L304GB', 'LS981FD', 'N19GU', 'N811ER', 'NG801EH', 'NG801LH', 'NG801RH', 'NG801TH', 'SE18UJ', 'SN381NW', 'SW1A0AA', 'SW1A0PW', 'SW1A1AA', 'SW1A2AA', 'SW1P3EU', 'SW1W0DT', 'TW89GS', 'W1A1AA', 'W1D4FA', 'W1N4DJ');
    // Add Overseas territories ?
    array_push($exceptions, 'AI-2640', 'ASCN1ZZ', 'STHL1ZZ', 'TDCU1ZZ', 'BBND1ZZ', 'BIQQ1ZZ', 'FIQQ1ZZ', 'GX111AA', 'PCRN1ZZ', 'SIQQ1ZZ', 'TKCA1ZZ');
    // End config


    $string = strtoupper(preg_replace('/\s/', '', $string)); // Remove the spaces and convert to uppercase.
    $exceptions = array_flip($exceptions);
    if(isset($exceptions[$string])){return $valid_return_value;} // Check for valid exception
    $length = strlen($string);
    if($length < 5 || $length > 7){return $invalid_return_value;} // Check for invalid length
    $letters = array_flip(range('A', 'Z')); // An array of letters as keys
    $numbers = array_flip(range(0, 9)); // An array of numbers as keys

    switch($length){
        case 7:
            if(!isset($letters[$string[0]], $letters[$string[1]], $numbers[$string[2]], $numbers[$string[4]], $letters[$string[5]], $letters[$string[6]])){break;}
            if(isset($letters[$string[3]]) || isset($numbers[$string[3]])){
                return $valid_return_value;
            }
        break;
        case 6:
            if(!isset($letters[$string[0]], $numbers[$string[3]], $letters[$string[4]], $letters[$string[5]])){break;}
            if(isset($letters[$string[1]], $numbers[$string[2]]) || isset($numbers[$string[1]], $letters[$string[2]]) || isset($numbers[$string[1]], $numbers[$string[2]])){
                return $valid_return_value;
            }
        break;
        case 5:
            if(isset($letters[$string[0]], $numbers[$string[1]], $numbers[$string[2]], $letters[$string[3]], $letters[$string[4]])){
                return $valid_return_value;
            }
        break;
    }

    return $invalid_return_value;
}

注意,我尚未添加 British Forces Post Office 非地理代码.

用法:

echo check_uk_postcode('AE3A 6AR').'<br>'; // valid
echo check_uk_postcode('Z9 9BA').'<br>'; // valid
echo check_uk_postcode('AE3A6AR').'<br>'; // valid
echo check_uk_postcode('EE34      6FR').'<br>'; // valid
echo check_uk_postcode('A23A 7AR').'<br>'; // invalid
echo check_uk_postcode('A23A   7AR').'<br>'; // invalid
echo check_uk_postcode('WA3334E').'<br>'; // invalid
echo check_uk_postcode('A2 AAR').'<br>'; // invalid

这篇关于不使用正则表达式的英国(GB)邮政编码验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆