C# 检查英国邮政编码验证 我需要查一下英国邮政编码,不要列入清单。< / P>

C# 检查英国邮政编码验证 我需要查一下英国邮政编码,不要列入清单。< / P>,c#,C#,该列表包含一系列外向邮政编码,以及与该外向邮政编码相关的一些数据,例如 AL St Albans B Birmingham BT Belfast TR Taunton TR21 Taunton X TR22 Taunton Y 我的目标是,当我得到一个邮政编码,例如B20 7TP,我可以搜索并找到伯明翰 有什么想法吗 这个问题与可能的答案不同,但在我的情况下,我需要检查完整的邮政编码与外部邮政编码。如果你有完整的邮政编码,只想使用外部编码,删除最后

该列表包含一系列外向邮政编码,以及与该外向邮政编码相关的一些数据,例如

AL     St Albans
B      Birmingham
BT     Belfast
TR     Taunton
TR21    Taunton X
TR22    Taunton Y
我的目标是,当我得到一个邮政编码,例如B20 7TP,我可以搜索并找到伯明翰

有什么想法吗


这个问题与可能的答案不同,但在我的情况下,我需要检查完整的邮政编码与外部邮政编码。

如果你有完整的邮政编码,只想使用外部编码,删除最后三个字符并使用剩余的字符。所有邮政编码以模式数字alpha结尾,因此删除这些字符将给出输出代码;任何不符合该模式的字符串或删除该子字符串后未提供有效输出代码的字符串都不是有效的邮政编码。()


如果您愿意承担外部(和基于Internet的)依赖关系,您可以考虑使用类似的东西,特别是API的outcodes部分。我与postcodes.io没有关联;我刚在谷歌上找到它

根据文档,/outcode将返回

  • 密码
  • 东方人
  • 北方人
  • 法典下的行政县
  • 《守则》下的地区/统一机构
  • 《守则》规定的行政/选举地区
  • WGS84逻辑图
  • WGS84纬度
  • 守则所包括的国家
  • 法典中的教区/社区
作为参考,对/outcodes/TA1的调用返回:

{
  "status": 200,
  "result": {
    "outcode": "TA1",
    "longitude": -3.10297767924529,
    "latitude": 51.0133987332761,
    "northings": 124359,
    "eastings": 322721,
    "admin_district": [
      "Taunton Deane"
    ],
    "parish": [
      "Taunton Deane, unparished area",
      "Bishop's Hull",
      "West Monkton",
      "Trull",
      "Comeytrowe"
   ],
    "admin_county": [
      "Somerset"
    ],
    "admin_ward": [
      "Taunton Halcon",
      "Bishop's Hull",
      "Taunton Lyngford",
      "Taunton Eastgate",
      "West Monkton",
      "Taunton Manor and Wilton",
      "Taunton Fairwater",
      "Taunton Killams and Mountfield",
      "Trull",
      "Comeytrowe",
      "Taunton Blackbrook and Holway"
    ],
    "country": [
      "England"
    ]
  }
}
如果您有完整的邮政编码,
/postcodes
端点将返回更详细的信息,我在这里不包括这些信息,但它确实将outcode和incode作为单独的字段包含在内


当然,我建议缓存对远程API的任何调用的结果。

从已知代码列表中构建正则表达式。请注意,正则表达式中已知代码的顺序很重要。您需要先使用较长的代码,然后再使用较短的代码

private void button1_Click(object sender, EventArgs e)
{
    textBoxLog.Clear();

    var regionList = BuildList();
    var regex = BuildRegex(regionList.Keys);

    TryMatch("B20 7TP", regionList, regex);
    TryMatch("BT1 1AB", regionList, regex);
    TryMatch("TR21 1AB", regionList, regex);
    TryMatch("TR0 00", regionList, regex);
    TryMatch("XX123", regionList, regex);
}

private static IReadOnlyDictionary<string, string> BuildList()
{
    Dictionary<string, string> result = new Dictionary<string, string>();

    result.Add("AL", "St Albans");
    result.Add("B", "Birmingham");
    result.Add("BT", "Belfast");
    result.Add("TR", "Taunton");
    result.Add("TR21", "Taunton X");
    result.Add("TR22", "Taunton Y");

    return result;
}

private static Regex BuildRegex(IEnumerable<string> codes)
{
    // Sort the code by length descending so that for example TR21 is sorted before TR and is found by regex engine
    // before the shorter match
    codes = from code in codes
            orderby code.Length descending
            select code;

    // Escape the codes to be used in the regex
    codes = from code in codes
            select Regex.Escape(code);

    // create Regex Alternatives
    string codesAlternatives = string.Join("|", codes.ToArray());

    // A regex that starts with any of the codes and then has any data following
    string lRegExSource = "^(" + codesAlternatives + ").*";

    return new Regex(lRegExSource, RegexOptions.IgnoreCase | RegexOptions.Singleline);
}


/// <summary>
/// Try to match the postcode to a region
/// </summary>
private bool CheckPostCode(string postCode, out string identifiedRegion, IReadOnlyDictionary<string, string> regionList, Regex regex)
{
    // Check whether we have any match at all
    Match match = regex.Match(postCode);
    bool result = match.Success;

    if (result)
    {
        // Take region code from first match group
        // and use it in dictionary to get region name
        string regionCode = match.Groups[1].Value;
        identifiedRegion = regionList[regionCode];
    }
    else
    {
        identifiedRegion = "";
    }

    return result;
}

private void TryMatch(string code, IReadOnlyDictionary<string, string> regionList, Regex regex)
{
    string region;

    if (CheckPostCode(code, out region, regionList, regex))
    {
        AppendLog(code + ": " + region);
    }
    else
    {
        AppendLog(code + ": NO MATCH");
    }
}

private void AppendLog(string log)
{
    textBoxLog.AppendText(log + Environment.NewLine);
}
private void按钮1\u单击(对象发送者,事件参数e)
{
textBoxLog.Clear();
var regionList=BuildList();
var regex=BuildRegex(regionList.Keys);
TryMatch(“B20 7TP”,regionList,regex);
TryMatch(“BT1 1AB”,regionList,regex);
TryMatch(“TR21 1AB”,regionList,regex);
TryMatch(“TR0 00”,regionList,regex);
TryMatch(“XX123”,regionList,regex);
}
私有静态IReadOnlyDictionary构建列表()
{
字典结果=新字典();
结果。添加(“AL”、“圣奥尔本”);
结果。添加(“B”、“伯明翰”);
结果。添加(“BT”、“贝尔法斯特”);
结果。添加(“TR”、“陶顿”);
结果。添加(“TR21”、“陶顿X”);
结果。添加(“TR22”、“陶顿Y”);
返回结果;
}
私有静态正则表达式BuildRegex(IEnumerable代码)
{
//按长度降序对代码进行排序,例如,TR21排序在TR之前,并由正则表达式引擎找到
//在短距离比赛之前
代码=从代码中的代码
orderby代码。长度递减
选择代码;
//转义要在正则表达式中使用的代码
代码=从代码中的代码
选择Regex.Escape(代码);
//创建正则表达式替代项
string codesAlternatives=string.Join(“|”,codes.ToArray());
//一种正则表达式,它以任何代码开头,然后具有以下任何数据
字符串lRegExSource=“^(“+codesAlternatives+”).*”;
返回新的正则表达式(lRegExSource,RegexOptions.IgnoreCase | RegexOptions.Singleline);
}
/// 
///尝试将邮政编码与地区匹配
/// 
私有bool CheckPostCode(字符串邮政编码、输出字符串标识区域、IREADONLYDICTIONAL区域列表、Regex Regex)
{
//看看我们有没有匹配的
Match Match=regex.Match(邮政编码);
bool结果=匹配。成功;
如果(结果)
{
//从第一个匹配组中获取区域代码
//并在字典中使用它来获取区域名称
字符串regionCode=match.Groups[1]。值;
identifiedRegion=regionList[regionCode];
}
其他的
{
identifiedRegion=“”;
}
返回结果;
}
私有void TryMatch(字符串代码、IReadOnlyDictionary regionList、Regex Regex)
{
弦区;
if(检查邮政编码(代码、地区外、地区列表、正则表达式))
{
附录日志(代码+”:“+区域);
}
其他的
{
附录日志(代码+“:不匹配”);
}
}
私有无效附加日志(字符串日志)
{
textBoxLog.AppendText(log+Environment.NewLine);
}
生成此输出:

B20 7TP:伯明翰 BT1 1AB:贝尔法斯特 TR21 1AB:Taunton X TR0 00:Taunton XX123:没有对手
供您参考,这里构建的正则表达式是
^(TR21 | TR22 | AL | BT | TR | B)。*

因此,如果您获得邮政编码
TR21 1AB
您想匹配
Taunton
还是
Taunton X
?同样,邮政编码
BT1 1AB
如何知道匹配
Belfast
而不是
Birmingham
?如果给出了邮政编码TR21 1AB,那么它需要匹配Taunton X,类似地,BT1 1AB需要匹配Belfast。谢谢。TR不是汤顿而是特鲁罗,,,,@wakthar我知道。挑战在于正确地将该逻辑定义为您的需求。@wakthar您可以使用dupe question链接中的正则表达式中的匹配组,这无疑是正确的做法-但不是问题的答案。@Jamiec我添加了更多细节;你能看到我错过了什么吗? B20 7TP: Birmingham BT1 1AB: Belfast TR21 1AB: Taunton X TR0 00: Taunton XX123: NO MATCH