一、起因
某日有人找到我,希望能将一些自然人身份证上的联系地址解析为行政区划地址,奇葩的是解析出来的这个行政区划地址还必须要求是一个行政区划地址列表里的值,如果能匹配上就把行政区划地址和自然人身份证地址关联起来,打个比方,将“广东省吴川市振文镇鱼九埠村XXX号XXX房” 解析为 “广东省吴川市振文镇”,然后把这两个地址关联后存放起来。查阅网上资料解决这个问题办法还是蛮多的,不过最后还是采用了自己的笨办法来实现:
二、实现逻辑:
步骤一、通过正则表达式将自然人身份证地址按省/自治区、市、区/县/乡/镇、街道/村委会/居委会五级行政机构分别取出
步骤二、由第一步解析出来的五级行政机构名称拿到行政区划地址列表里进行筛选,得到五个Datatable
步骤三、取这五个Datatable的交集(相同项)。从理论上可以获得一个交集,默认取交集的第一行此记录就是自然人身份证地址对应的行政区划地址
三、关键代码
步骤一:
public static void ParseAddress(string address,
out string province,
out string city,
out string county,
out string town,
out string village)
{
string regex = @"(?<province>[^省]+自治区|.*?省)?(?<city>[^市]+自治州|.*?地区|.*?行政单位|.+盟|市辖区|.*?市)?(?<county>[^乡]+乡|[^县]+县|[^区]+区|[^市]+市|.+旗|.+海域|.+岛)?(?<town>[^区]+区|.+镇|.+办事处)?(?<village>.街道|.村委会|.居委会|.农场)?(?<other>.*)";
var m = Regex.Match(address, regex, RegexOptions.IgnoreCase);
province = m.Groups["province"].Value;//省
city = m.Groups["city"].Value;//市
county = m.Groups["county"].Value;//县
town = m.Groups["town"].Value;//镇
village = m.Groups["village"].Value;//街道
}
步骤三:
static List<object> FindCommonRowsInXzqhColumn(params DataTable[] dataTables)
{
// 用于存储每个 DataTable 中 xzqh 列的值
List<List<object>> allXzqhValues = new List<List<object>>();
foreach (var dt in dataTables)
{
// 检查 DataTable 是否为空
if (dt == null || dt.Rows.Count == 0)
{
continue;
}
List<object> xzqhValues = new List<object>();
foreach (DataRow row in dt.Rows)
{
xzqhValues.Add(row["xzqh"]);
}
allXzqhValues.Add(xzqhValues);
}
if (allXzqhValues.Count == 0)
{
return new List<object>();
}
// 找出所有列表中的交集
var commonValues = allXzqhValues[0];
for (int i = 1; i < allXzqhValues.Count; i++)
{
commonValues = commonValues.Intersect(allXzqhValues[i]).ToList();
}
return commonValues;
}
四、输出效果:
输出效果还不错,80个自然人身份证联系地址可以在行政区划地址表中解析出78个,没有解析出来的,一个是由于自然人身份证上写的是“广西”不带“省”正则匹配不出来;第二个则是行政区划地址表里压根没有自然人身份证联系地址解析出来的行政机构。