package com.skyversation.poiaddr.util; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; public class AddressMatcher { // 静态数据存储省市信息,包含简称映射 private static final Map> PROVINCE_CITY_MAP = new HashMap<>(); private static final Map ABBREVIATION_PROVINCE_MAP = new HashMap<>(); private static final Map ABBREVIATION_CITY_MAP = new HashMap<>(); private static final Map CITY_PROVINCE_MAP = new HashMap<>(); static { // 初始化数据 addProvinceAndCities("北京市", "东城区", "西城区", "朝阳区", "丰台区", "石景山区", "海淀区", "门头沟区", "房山区", "通州区", "顺义区", "昌平区", "大兴区", "怀柔区", "平谷区", "密云区", "延庆区"); addProvinceAndCities("天津市", "和平区", "河东区", "河西区", "南开区", "河北区", "红桥区", "东丽区", "西青区", "津南区", "北辰区", "武清区", "宝坻区", "滨海新区", "宁河区", "静海区", "蓟州区"); addProvinceAndCities("河北省", "石家庄市", "唐山市", "秦皇岛市", "邯郸市", "邢台市", "保定市", "张家口市", "承德市", "沧州市", "廊坊市", "衡水市"); addProvinceAndCities("山西省", "太原市", "大同市", "阳泉市", "长治市", "晋城市", "朔州市", "晋中市", "运城市", "忻州市", "临汾市", "吕梁市"); addProvinceAndCities("内蒙古自治区", "呼和浩特市", "包头市", "乌海市", "赤峰市", "通辽市", "鄂尔多斯市", "呼伦贝尔市", "巴彦淖尔市", "乌兰察布市"); addProvinceAndCities("辽宁省", "沈阳市", "大连市", "鞍山市", "抚顺市", "本溪市", "丹东市", "锦州市", "营口市", "阜新市", "辽阳市", "盘锦市", "铁岭市", "朝阳市", "葫芦岛市"); addProvinceAndCities("吉林省", "长春市", "吉林市", "四平市", "辽源市", "通化市", "白山市", "松原市", "白城市"); addProvinceAndCities("黑龙江省", "哈尔滨市", "齐齐哈尔市", "鸡西市", "鹤岗市", "双鸭山市", "大庆市", "伊春市", "佳木斯市", "七台河市", "牡丹江市", "黑河市", "绥化市"); addProvinceAndCities("上海市", "黄浦区", "徐汇区", "长宁区", "静安区", "普陀区", "虹口区", "杨浦区", "闵行区", "宝山区", "嘉定区", "浦东新区", "金山区", "松江区", "青浦区", "奉贤区", "崇明区"); addProvinceAndCities("江苏省", "南京市", "无锡市", "徐州市", "常州市", "苏州市", "南通市", "连云港市", "淮安市", "盐城市", "扬州市", "镇江市", "泰州市", "宿迁市"); addProvinceAndCities("浙江省", "杭州市", "宁波市", "温州市", "嘉兴市", "湖州市", "绍兴市", "金华市", "衢州市", "舟山市", "台州市", "丽水市"); addProvinceAndCities("安徽省", "合肥市", "芜湖市", "蚌埠市", "淮南市", "马鞍山市", "淮北市", "铜陵市", "安庆市", "黄山市", "阜阳市", "宿州市", "滁州市", "六安市", "宣城市", "池州市", "亳州市"); addProvinceAndCities("福建省", "福州市", "厦门市", "莆田市", "三明市", "泉州市", "漳州市", "南平市", "龙岩市", "宁德市"); addProvinceAndCities("江西省", "南昌市", "景德镇市", "萍乡市", "九江市", "鹰潭市", "赣州市", "吉安市", "宜春市", "抚州市", "上饶市"); addProvinceAndCities("山东省", "济南市", "青岛市", "淄博市", "枣庄市", "东营市", "烟台市", "潍坊市", "济宁市", "泰安市", "威海市", "日照市", "临沂市", "德州市", "聊城市", "滨州市", "菏泽市"); addProvinceAndCities("河南省", "郑州市", "开封市", "洛阳市", "平顶山市", "安阳市", "鹤壁市", "新乡市", "焦作市", "濮阳市", "许昌市", "漯河市", "三门峡市", "南阳市", "商丘市", "信阳市", "周口市", "驻马店市"); addProvinceAndCities("湖北省", "武汉市", "黄石市", "十堰市", "宜昌市", "襄阳市", "鄂州市", "荆门市", "孝感市", "荆州市", "黄冈市", "咸宁市", "随州市"); addProvinceAndCities("湖南省", "长沙市", "株洲市", "湘潭市", "衡阳市", "邵阳市", "岳阳市", "常德市", "张家界市", "益阳市", "郴州市", "永州市", "怀化市", "娄底市"); addProvinceAndCities("广东省", "广州市", "深圳市", "珠海市", "汕头市", "佛山市", "韶关市", "湛江市", "肇庆市", "江门市", "茂名市", "惠州市", "梅州市", "汕尾市", "河源市", "阳江市", "清远市", "东莞市", "潮州市", "揭阳市", "云浮市"); addProvinceAndCities("广西自治区", "南宁市", "柳州市", "桂林市", "梧州市", "北海市", "防城港市", "钦州市", "贵港市", "玉林市", "百色市", "贺州市", "河池市", "来宾市", "崇左市"); addProvinceAndCities("海南省", "海口市", "三亚市", "三沙市", "儋州市"); addProvinceAndCities("重庆市", "万州区", "黔江区", "涪陵区", "渝中区", "大渡口区", "江北区", "沙坪坝区", "九龙坡区", "南岸区", "北碚区", "綦江区", "大足区", "渝北区", "巴南区", "黔江区", "长寿区", "江津区", "合川区", "永川区", "南川区", "璧山区", "铜梁区", "潼南县", "荣昌区", "开州区", "梁平区", "武隆区", "城口县", "丰都县", "垫江县", "忠县", "云阳县", "奉节县", "巫山县", "巫溪县"); addProvinceAndCities("四川省", "成都市", "自贡市", "攀枝花市", "泸州市", "德阳市", "绵阳市", "广元市", "遂宁市", "内江市", "乐山市", "南充市", "眉山市", "宜宾市", "广安市", "达州市", "雅安市", "巴中市", "资阳市"); addProvinceAndCities("贵州省", "贵阳市", "六盘水市", "遵义市", "安顺市", "毕节市", "铜仁市"); addProvinceAndCities("云南省", "昆明市", "曲靖市", "玉溪市", "保山市", "昭通市", "丽江市", "普洱市", "临沧市"); addProvinceAndCities("西藏自治区", "拉萨市", "日喀则市", "昌都市", "林芝市", "山南市", "那曲市", "阿里地区"); addProvinceAndCities("陕西省", "西安市", "铜川市", "宝鸡市", "咸阳市", "渭南市", "延安市", "汉中市", "榆林市", "安康市", "商洛市"); addProvinceAndCities("甘肃省", "兰州市", "嘉峪关市", "金昌市", "白银市", "天水市", "武威市", "张掖市", "平凉市", "酒泉市", "庆阳市", "定西市", "陇南市"); addProvinceAndCities("青海省", "西宁市", "海东市"); addProvinceAndCities("宁夏自治区", "银川市", "石嘴山市", "吴忠市", "固原市", "中卫市"); addProvinceAndCities("新疆自治区", "乌鲁木齐市", "克拉玛依市", "吐鲁番市", "哈密市"); // 生成简称映射 generateAbbreviations(); // 生成城市到省份的映射 generateCityProvinceMap(); } private static void addProvinceAndCities(String province, String... cities) { PROVINCE_CITY_MAP.put(province, Arrays.asList(cities)); } private static void generateAbbreviations() { for (String province : PROVINCE_CITY_MAP.keySet()) { String abbreviation = province.replaceAll("省|市|自治区", ""); ABBREVIATION_PROVINCE_MAP.put(abbreviation, province); } for (Map.Entry> entry : PROVINCE_CITY_MAP.entrySet()) { for (String city : entry.getValue()) { String abbreviation = city.replaceAll("市|区|县", ""); ABBREVIATION_CITY_MAP.put(abbreviation, city); } } } private static void generateCityProvinceMap() { for (Map.Entry> entry : PROVINCE_CITY_MAP.entrySet()) { String province = entry.getKey(); for (String city : entry.getValue()) { CITY_PROVINCE_MAP.put(city, province); } } } /** * 根据输入的地址匹配省和市 * * @param address 输入的地址 * @return 包含省和市的数组,若未匹配到则返回 null */ public static String[] matchProvinceAndCity(String address) { // 先尝试匹配完整的省份名称 for (String province : PROVINCE_CITY_MAP.keySet()) { if (address.contains(province)) { for (String city : PROVINCE_CITY_MAP.get(province)) { if (address.contains(city) && !isPartOfRoadName(address, city)) { return new String[]{province, city}; } } if (isMunicipality(province)) { return new String[]{province, province}; } return new String[]{province, ""}; } } // 尝试匹配省份简称 for (Map.Entry entry : ABBREVIATION_PROVINCE_MAP.entrySet()) { String abbreviation = entry.getKey(); String province = entry.getValue(); if (address.contains(abbreviation) && !isPartOfRoadName(address, abbreviation)) { for (String city : PROVINCE_CITY_MAP.get(province)) { String cityAbbreviation = city.replaceAll("市", ""); if (address.contains(cityAbbreviation) && !isPartOfRoadName(address, cityAbbreviation)) { return new String[]{province, city}; } } if (isMunicipality(province)) { return new String[]{province, province}; } return new String[]{province, ""}; } } // 尝试根据城市反向查找省份 for (Map.Entry entry : ABBREVIATION_CITY_MAP.entrySet()) { String cityAbbreviation = entry.getKey(); String city = entry.getValue(); if (address.contains(cityAbbreviation) && !isPartOfRoadName(address, cityAbbreviation)) { String province = CITY_PROVINCE_MAP.get(city); if (province != null) { return new String[]{province, city}; } else { return new String[]{"", city}; } } } return null; } private static boolean isMunicipality(String province) { return province.equals("北京市") || province.equals("天津市") || province.equals("上海市") || province.equals("重庆市"); } /** * 只有返回为false时,才会检验成功 * * @param address * @param name * @return */ private static boolean isPartOfRoadName(String address, String name) { boolean is = address.contains(name + "路") || address.contains(name + "大道") || address.contains(name + "街") || address.contains(name + "社区") || address.contains("镇江"); if (!is) { int index = address.indexOf(name) + name.length(); String endStr = address.substring(index, Math.min((index + 2), address.length())); if (endStr.contains("路") || endStr.contains("道") || endStr.contains("街")) { return true; } else { is = false; } } return is; } public static void main(String[] args) { String address = "石家庄开封南路正定县新疆路123号"; String[] result = matchProvinceAndCity(address); if (result != null) { System.out.println("省: " + result[0]); System.out.println("市: " + result[1]); } else { System.out.println("未匹配到省和市"); } } }