前言
前面我们提到过文本地址智能识别组件的暴力解析方式,直接如何强行匹配地址信息,但是这种方式很难维护.这次我们通过别的方式去实现地址识别的功能,达到和数据库实时同步,并且自动补全的功能,当我们地址里面输入湖南省岳麓区时自动匹配长沙市,但输入长沙市岳麓区时,自动匹配出湖南省,达到实际需求中真正的智能识别文本地址信息
方案
大概的思路是数据库中存在想对应的省市区三级甚至四级的数据,没有数据可以自行去网上下载一份导入数据库,相关的数据操作按钮功能我就不一一描述了,我们通过数据库地址的级别功能找到对应的关联关系,通过连表查询出对应的上下级地址名称,然后把相关的值传进来返回对应的地址信息再处理相关的业务,可能数据结构和业务逻辑不一样,这就需要自行处理了.
首先我们查询对应的参考数据
SQL如下
SELECT * FROM kd_region WHERE region_name = '北京市'
UNION
SELECT * FROM kd_region WHERE region_parent_id = '110000'
UNION
SELECT * FROM kd_region WHERE region_parent_id = '110100'
如上可看出数据库的地址表数据结构是有region_id(地址ID)和region_parent_id(父级ID),region_type(1省,2市,3区,4街道)这些关键信息所组成.
编写匹配地址业务SQL
SELECT
t2.province_code provinceCode,
t2.province_name province,
t2.city_name city,
t2.county_name county
FROM
((
SELECT
r.region_id province_code,
r.region_name province_name,
r1.region_name city_name,
r2.region_name county_name
FROM
kd_region r
LEFT JOIN kd_region r1 ON r.region_id = r1.region_parent_id AND
r1.region_type = 2 AND r1.is_del = 0
LEFT JOIN kd_region r2 ON r1.region_id = r2.region_parent_id AND r2.is_del
= 0
WHERE
r.region_type = 1 AND r.is_del= 0
) ) t2 WHERE
(
INSTR('湖南省岳麓区XX路XX区',t2.province_name)
OR
INSTR('湖南省岳麓区XX路XX区',t2.city_name)
)
AND INSTR('湖南省岳麓区XX路XX区',t2.county_name)
通过关联地址表的父级ID查询出三级菜单,由于我们的地址有些是直辖市自治县这种特殊地址,所以关联第三级的时候我们的地址级别只要不为1或者2都可以,不然会导致部分特殊地址丢失的情况.
由于地址会自动找出丢失的第一级或者第二级,当出现重名的地址时,可以考虑随时获取识别到的地址
具体业务处理
/** * 识别相关信息:QQ1025032391 * @param request * @return */
@RequestMapping("/textRecognition")
public ApiResult textRecogin(HttpServletRequest request) {
String functionId = "/textRecognition";
String text = request.getParameter("text");
if (StringUtils.isEmpty(text)) {
return error(functionId, "请传入文本信息");
}
String regEx = "[`~!@#$%^&*()\\-+={}':;,\\[\\].<>/?¥%…()_+|【】‘;:”“’。,、?\\s]";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(text);
text = m.replaceAll(" ");
String[] textArr = text.split("\\s+");
if (textArr.length != 3) {
return error(functionId, "文本信息传入不正确");
}
List<String> dataList = new ArrayList<String>(Arrays.asList(textArr));
Map<String, String> data = new HashMap<String, String> ();
for (int i = 0; i < dataList.size(); i++) {
List<RegionDTO> recognition = regionService.getTextRecognition(dataList.get(i));
if (recognition.size() > 0) {
if (dataList.get(i).length() > 50) {
return error(functionId, "地址长度不能超过50位");
}
//如果多个结果,可考虑随机匹配
RegionDTO region = recognition.get(new Random().nextInt(recognition.size()));
//不随机匹配
// RegionDTO region = recognition.get(new Random().nextInt(recognition.size()));
data.put("provinceCode", region.getProvinceCode());
data.put("province", region.getProvince());
data.put("city", region.getCity());
data.put("county", region.getCounty());
String detail = dataList.get(i).replace(region.getProvince(), "").replace(region.getCity(), "").replace(region.getCounty(), "");
data.put("detail", detail);
data.put("text", Pattern.compile("\\s+").matcher(text.replace(dataList.get(i), region.getProvince()+region.getCity()+region.getCounty() + detail)).replaceAll(","));
dataList.remove(i);
break;
}
}
if (data.isEmpty() || StringUtils.isEmpty(data.get("county"))) {
return error(functionId, "未匹配到地址信息");
}
for (int i = 0; i < dataList.size(); i++) {
if ((Pattern.compile("[0-9]*")).matcher(dataList.get(i)).matches()) {
if (dataList.get(i).length() > 17 || dataList.get(i).length() < 7) {
return error(functionId, "电话号码长度为7-17位");
}
data.put("phone", dataList.get(i));
dataList.remove(i);
break;
}
}
if (StringUtils.isEmpty(data.get("phone"))) {
return error(functionId, "未识别到手机号");
}
if (dataList.get(0).length() > 10) {
return error(functionId, "姓名不能超过10位");
}
data.put("name", dataList.get(0));
Map tempMap = data;
Map<String,Object> resultData = tempMap;
return success(functionId, ApiResult.SUCCESS_MESSAGE, resultData);
}
如上传入文本信息,就可以识别地址信息了,可能具体的业务场景不一样,可以根据自己的业务场景适当变更,但地址识别是测试过了,完全可以使用的.
今天的文章文本地址智能识别组件(二)分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/40086.html