文本地址智能识别组件(二)

文本地址智能识别组件(二)前言前面我们提到过文本地址智能识别组件的暴力解析方式,直接如何强行匹配地址信息,但是这种方式很难维护.这次我们通过别的方式去实现地址识别的功能,达到和数据库实时同步,并且自动补全的功能,当我们地址里面输入湖南省岳麓区时自动匹配长沙市,但输入长沙市岳麓区时,自动匹配出湖南省,达到实际需求中真正的智能识别文本地址信息方案大概的思路是数据库中存在想对应的省市区三级甚至四级的数据,没有数据可以自行去…

前言

前面我们提到过文本地址智能识别组件的暴力解析方式,直接如何强行匹配地址信息,但是这种方式很难维护.这次我们通过别的方式去实现地址识别的功能,达到和数据库实时同步,并且自动补全的功能,当我们地址里面输入湖南省岳麓区时自动匹配长沙市,但输入长沙市岳麓区时,自动匹配出湖南省,达到实际需求中真正的智能识别文本地址信息

方案

大概的思路是数据库中存在想对应的省市区三级甚至四级的数据,没有数据可以自行去网上下载一份导入数据库,相关的数据操作按钮功能我就不一一描述了,我们通过数据库地址的级别功能找到对应的关联关系,通过连表查询出对应的上下级地址名称,然后把相关的值传进来返回对应的地址信息再处理相关的业务,可能数据结构和业务逻辑不一样,这就需要自行处理了.

首先我们查询对应的参考数据
查询的地址结果
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

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注