Java实现根据地址智能识别省市区县及详细地址Util_java地址如何提取省市县区


一、需求

根据OCR识别出的身份证地址或者用户输入的地址,智能识别出用户的省、市、区/县和详细地址信息。

二、思路

解析给到接口的完整地址fullAddress,逐个匹配省province、市city、区/县area、详细地址detail,然后将 province+city+area+detail 返回即可。

PS:需要考虑一些情况:

1、四个直辖市(北京市、上海市、天津市、重庆市)。直辖市的完整地址fullAddress只有省、县/区

2、完整地址fullAddress只有省、区/县

3、市与区/县重名

4、区/县与区/县重名

三、实现代码

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 身份证信息分析工具类Util
 */
@Slf4j
public class AnalysisIdCardUtil {

    /**
     * 获取详细地址
     *
     * @param fullAddress 身份证完整地址
     */
    public static String getDetailedAddress(String fullAddress) {
        String[] addressArrays = spliceDetailedAddress(fullAddress);
        return addressArrays[addressArrays.length - 1];
    }

    /**
     * 获取省市区地址,如:安徽省合肥市包河区
     *
     * @param fullAddress 身份证完整地址
     */
    public static String getPcaAddress(String fullAddress) {
        String[] addressArrays = spliceDetailedAddress(fullAddress);
        StringBuilder areaBuffer = new StringBuilder();
        for (int i = 0; i < addressArrays.length - 1; i++) {
            if (StringUtils.isNotEmpty(addressArrays[i])) {
                areaBuffer.append(addressArrays[i]);
            }
        }
        return areaBuffer.toString();
    }

    /**
     * 身份证完成地址拆分为[省、市、区、详细地址]数组,如:[安徽省, 合肥市, 包河区, 幸福大街001号]
     *
     * @param fullAddress 身份证完整地址
     */
    public static String[] spliceDetailedAddress(String fullAddress) {
        String[] arr = new String[4];
        try {
            String tempStr = fullAddress;
            // 省
            String province = null;
            int provinceIdx = processProvince(tempStr);
            if (provinceIdx > -1) {
                province = tempStr.substring(0, provinceIdx + 1);
                tempStr = tempStr.substring(provinceIdx + 1);
            }
            // 市
            String city = null;
            int cityIdx = processCity(tempStr);
            if (cityIdx > -1) {
                city = tempStr.substring(0, cityIdx + 1);
                tempStr = tempStr.substring(cityIdx + 1);
            }
            // 区
            String county = null;
            int countyIdx = processCounty(tempStr);
            if (countyIdx > -1) {
                county = tempStr.substring(0, countyIdx + 1);
                tempStr = tempStr.substring(countyIdx + 1);
            }
            String street = tempStr;
            arr[0] = province;
            arr[1] = city;
            arr[2] = county;
            arr[3] = street;
        } catch (Exception e) {
            log.error("身份证详细地址转义失败:{}", e.getMessage());
        }
        return arr;
    }

    /**
     * 拆分身份证完整地址中的省份信息
     *
     * @param address 地址
     */
    private static int processProvince(String address) {
        int[] idx = new int[3];
        int provinceIdx;
        if ((provinceIdx = address.indexOf("省")) > -1) {
            idx[0] = provinceIdx;
        }
        if ((provinceIdx = address.indexOf("市")) > -1) {
            idx[1] = provinceIdx;
        }
        if ((provinceIdx = address.indexOf("区")) > -1) {
            idx[2] = provinceIdx;
        }
        Arrays.sort(idx);
        for (int j : idx) {
            if (j > 0) {
                return j;
            }
        }
        return provinceIdx;
    }

    /**
     * 拆分身份证完整地址中的市区/县/自治州信息
     *
     * @param address 地址
     */
    private static int processCity(String address) {
        int[] idx = new int[7];
        int cityIdx = -1;
        if ((cityIdx = address.indexOf("县")) > -1) {
            idx[0] = cityIdx;
        }
        if ((cityIdx = address.indexOf("自治州")) > -1) {
            idx[1] = cityIdx + 2;
        }
        if ((cityIdx = address.indexOf("市辖区")) > -1) {
            idx[2] = cityIdx + 2;
        }
        if ((cityIdx = address.indexOf("市")) > -1) {
            idx[3] = cityIdx;
        }
        if ((cityIdx = address.indexOf("区")) > -1) {
            idx[4] = cityIdx;
        }
        if ((cityIdx = address.indexOf("地区")) > -1) {
            idx[5] = cityIdx + 1;
        }
        if ((cityIdx = address.indexOf("盟")) > -1) {
            idx[6] = cityIdx;
        }
        Arrays.sort(idx);
        for (int j : idx) {
            if (j > 0) {
                return j;
            }
        }
        return cityIdx;
    }

    /**
     * 拆分身份证完整地址中的县/旗/岛信息
     *
     * @param address 地址
     */
    private static int processCounty(String address) {
        int[] idx = new int[6];
        int countyIdx;
        if ((countyIdx = address.indexOf("县")) > -1) {
            idx[0] = countyIdx;
        }
        if ((countyIdx = address.indexOf("旗")) > -1) {
            idx[1] = countyIdx;
        }
        if ((countyIdx = address.indexOf("海域")) > -1) {
            idx[2] = countyIdx + 1;
        }
        if ((countyIdx = address.indexOf("市")) > -1) {
            idx[3] = countyIdx;
        }
        if ((countyIdx = address.indexOf("区")) > -1) {
            idx[4] = countyIdx;
        }
## 最后

**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。**

![img](https://img-blog.csdnimg.cn/img_convert/4d944bc682cf242566013f7367272989.png)

![img](https://img-blog.csdnimg.cn/img_convert/bd3d4b1f874bb40d449c8471f9841811.png)

![img](https://img-blog.csdnimg.cn/img_convert/a29c8c6a9dcb55582d956cd1e36919b2.png)

![img](https://img-blog.csdnimg.cn/img_convert/4d1bd1c8ef1ab8328679cca84fbd7958.png)

![img](https://img-blog.csdnimg.cn/img_convert/1e11b588a5bc2c16ed6a297d9a7ebe7e.png)

 

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!**

[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618653875)

**由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**

 

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点!真正的体系化!**

[**如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!**](https://bbs.csdn.net/topics/618653875)

**由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
识别Java地址中的信息,可以使用第三方的地址库或者在线API来实现。以下是一个示例代码,使用了百度地图API来识别地址: ```java import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import org.apache.commons.io.IOUtils; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; public class AddressRecognizer { private static final String BAIDU_MAP_API_URL = "http://api.map.baidu.com/geocoding/v3/?address=%s&output=json&ak=%s"; public static void main(String[] args) throws Exception { String address = "浙江杭州西湖文三路478号浙江大学紫金港校"; Map<String, String> addressInfo = recognizeAddress(address, "your_baidu_map_api_ak"); System.out.println(addressInfo); } public static Map<String, String> recognizeAddress(String address, String apiKey) throws Exception { String url = String.format(BAIDU_MAP_API_URL, address, apiKey); String json = IOUtils.toString(new URL(url), StandardCharsets.UTF_8); JSONObject result = JSON.parseObject(json).getJSONObject("result"); JSONObject location = result.getJSONObject("location"); String latitude = location.getString("lat"); String longitude = location.getString("lng"); JSONArray addressComponents = result.getJSONArray("addressComponent"); String province = addressComponents.getJSONObject(0).getString("short_name"); String city = addressComponents.getJSONObject(1).getString("short_name"); String district = addressComponents.getJSONObject(2).getString("short_name"); String street = addressComponents.getJSONObject(3).getString("short_name"); Map<String, String> addressInfo = new HashMap<>(); addressInfo.put("province", province); addressInfo.put("city", city); addressInfo.put("district", district); addressInfo.put("street", street); addressInfo.put("latitude", latitude); addressInfo.put("longitude", longitude); return addressInfo; } } ``` 该代码会输出地址中的信息,以及地址所在位置的经纬度。需要替换 `your_baidu_map_api_ak` 为你的百度地图API的AK密钥。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值