|
@@ -0,0 +1,170 @@
|
|
|
|
+package com.dayou.utils;
|
|
|
|
+
|
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
|
+import com.dayou.dto.AddressDTO;
|
|
|
|
+import com.dayou.exception.ErrorCode;
|
|
|
|
+
|
|
|
|
+import java.util.Arrays;
|
|
|
|
+import java.util.List;
|
|
|
|
+import java.util.regex.Matcher;
|
|
|
|
+import java.util.regex.Pattern;
|
|
|
|
+
|
|
|
|
+public class AddressUtil {
|
|
|
|
+
|
|
|
|
+ private static final Pattern PROVINCE_PATTERN = Pattern.compile("(?<province>.+省|.+自治区)");
|
|
|
|
+ private static final Pattern CITY_PATTERN = Pattern.compile("(?<city>.+市|.+自治州|.+盟)");
|
|
|
|
+ private static final Pattern DISTRICT_PATTERN = Pattern.compile("(?<district>.+区|.+县|.+旗)");
|
|
|
|
+ private static final Pattern TOWN_PATTERN = Pattern.compile("(?<town>.+街道|.+镇|.+乡)");
|
|
|
|
+ private static final Pattern COMMUNITY_PATTERN = Pattern.compile("(?<community>.+社区|.+园区|.+村)");
|
|
|
|
+ private static final Pattern ROAD_PATTERN = Pattern.compile("(?<road>.+路.+?段|.+路|.+巷|.+?街.+?段|.+?街|.+?道.+?段)");
|
|
|
|
+ private static final Pattern ROAD_NUMBER_PATTERN = Pattern.compile("(?<roadNumber>\\d+号附\\d+号|\\d+号)");
|
|
|
|
+ private static final Pattern BUILDING_PATTERN = Pattern.compile("(?<building>\\d+楼|\\d+栋|\\d+幢)");
|
|
|
|
+ private static final Pattern UNIT_PATTERN = Pattern.compile("(?<unit>\\d+单元)");
|
|
|
|
+ private static final Pattern FLOOR_PATTERN = Pattern.compile("(?<floor>-?\\d+层|-?\\d+楼)");
|
|
|
|
+ private static final Pattern ROOM_PATTERN = Pattern.compile("(?<room>\\d+室\\d+号|\\d+室|\\d+号)");
|
|
|
|
+
|
|
|
|
+ private static final String SQ = "社区";
|
|
|
|
+
|
|
|
|
+ private static final String YQ = "园区";
|
|
|
|
+ /**
|
|
|
|
+ *
|
|
|
|
+ * @param address 地址字符串
|
|
|
|
+ * @return 标准地址对象
|
|
|
|
+ */
|
|
|
|
+ public static AddressDTO parseAddress(String address) {
|
|
|
|
+ AddressDTO result = new AddressDTO();
|
|
|
|
+ address = address.replaceAll(SQ,"").replaceAll(YQ,"");
|
|
|
|
+ // 依次匹配每个级别的地址部分,并从剩余字符串中继续解析
|
|
|
|
+ String remaining = address;
|
|
|
|
+ result.setProvince(extractAndRemove(PROVINCE_PATTERN, remaining));
|
|
|
|
+ remaining = removePrefix(remaining, result.getProvince());
|
|
|
|
+
|
|
|
|
+ result.setCity(extractAndRemove(CITY_PATTERN, remaining));
|
|
|
|
+ remaining = removePrefix(remaining, result.getCity());
|
|
|
|
+
|
|
|
|
+ result.setDistrict(extractAndRemove(DISTRICT_PATTERN, remaining));
|
|
|
|
+ remaining = removePrefix(remaining, result.getDistrict());
|
|
|
|
+
|
|
|
|
+ result.setTown(extractAndRemove(TOWN_PATTERN, remaining));
|
|
|
|
+ remaining = removePrefix(remaining, result.getTown());
|
|
|
|
+
|
|
|
|
+// result.setCommunity(extractAndRemove(COMMUNITY_PATTERN, remaining));
|
|
|
|
+// remaining = removePrefix(remaining, result.getCommunity());
|
|
|
|
+
|
|
|
|
+ result.setRoad(extractAndRemove(ROAD_PATTERN, remaining));
|
|
|
|
+ remaining = removePrefix(remaining, result.getRoad());
|
|
|
|
+
|
|
|
|
+ result.setRoadNumber(extractAndRemove(ROAD_NUMBER_PATTERN, remaining));
|
|
|
|
+ remaining = removePrefix(remaining, result.getRoadNumber());
|
|
|
|
+
|
|
|
|
+ result.setBuilding(extractAndRemove(BUILDING_PATTERN, remaining));
|
|
|
|
+ remaining = removePrefix(remaining, result.getBuilding());
|
|
|
|
+
|
|
|
|
+ result.setUnit(extractAndRemove(UNIT_PATTERN, remaining));
|
|
|
|
+ remaining = removePrefix(remaining, result.getUnit());
|
|
|
|
+
|
|
|
|
+ result.setFloor(extractAndRemove(FLOOR_PATTERN, remaining));
|
|
|
|
+ remaining = removePrefix(remaining, result.getFloor());
|
|
|
|
+
|
|
|
|
+ result.setRoom(extractAndRemove(ROOM_PATTERN, remaining));
|
|
|
|
+ remaining = removePrefix(remaining, result.getRoom());
|
|
|
|
+
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static String extractAndRemove(Pattern pattern, String input) {
|
|
|
|
+ Matcher matcher = pattern.matcher(input);
|
|
|
|
+ if (matcher.find()) {
|
|
|
|
+ return matcher.group().trim();
|
|
|
|
+ }
|
|
|
|
+ return "";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static String removePrefix(String input, String prefix) {
|
|
|
|
+ if (prefix == null || input == null) {
|
|
|
|
+ return input;
|
|
|
|
+ }
|
|
|
|
+ return input.replaceFirst(Pattern.quote(prefix), "").trim();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 获取到路号的全地址
|
|
|
|
+ * @param address
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public static String getRoadNumberAddress(String address) {
|
|
|
|
+ if (StrUtil.isNotBlank(address)) {
|
|
|
|
+ AddressDTO addressDTO = parseAddress(address);
|
|
|
|
+ return new StringBuffer().append(addressDTO.getProvince()!=null?addressDTO.getProvince():"")
|
|
|
|
+ .append(addressDTO.getCity()!=null?addressDTO.getCity():"")
|
|
|
|
+ .append(addressDTO.getDistrict()!=null?addressDTO.getDistrict():"")
|
|
|
|
+ .append(addressDTO.getTown()!=null?addressDTO.getTown():"")
|
|
|
|
+ .append(addressDTO.getCommunity()!=null?addressDTO.getCommunity():"")
|
|
|
|
+ .append(addressDTO.getRoad()!=null?addressDTO.getRoad():"")
|
|
|
|
+ .append(addressDTO.getRoadNumber()!=null?addressDTO.getRoadNumber():"").toString();
|
|
|
|
+ }else {
|
|
|
|
+ ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR,"地址为空");
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 获取道路名字和路号
|
|
|
|
+ * @param address
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public static String getRoadAndRoadNumber(String address) {
|
|
|
|
+ if (StrUtil.isNotBlank(address)) {
|
|
|
|
+ AddressDTO addressDTO = parseAddress(address);
|
|
|
|
+ String road = addressDTO.getRoad();
|
|
|
|
+ if (StrUtil.isNotBlank(road)) {
|
|
|
|
+ if (StrUtil.isNotBlank(addressDTO.getRoadNumber())) {
|
|
|
|
+ return new StringBuilder(road).append(addressDTO.getRoadNumber()).toString();
|
|
|
|
+ }
|
|
|
|
+ return road;
|
|
|
|
+ }else {
|
|
|
|
+ return "";
|
|
|
|
+ }
|
|
|
|
+ }else {
|
|
|
|
+ ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR,"地址为空");
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 尝试从地址中解析出小区名字
|
|
|
|
+ * @param address
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public static String getCommunityNameFromAddress(String address) {
|
|
|
|
+ try {
|
|
|
|
+ String roadAndRoadNumber = getRoadAndRoadNumber(address);
|
|
|
|
+ if (StrUtil.isNotBlank(roadAndRoadNumber)) {
|
|
|
|
+ AddressDTO addressDTO = parseAddress(address);
|
|
|
|
+ String building = addressDTO.getBuilding();
|
|
|
|
+ if (StrUtil.isNotBlank(building)) {
|
|
|
|
+ String communityName = address.split(roadAndRoadNumber)[1].split(building)[0];
|
|
|
|
+ if (StrUtil.isNotBlank(communityName)) {
|
|
|
|
+ return communityName;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR,"小区名称解析失败");
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ public static void main(String[] args) {
|
|
|
|
+ String location = "成都市天府新区万安镇麓山大道二段20号附9号麓山国际社区3栋2单元2层3号住宅";
|
|
|
|
+ //String location = "成都市天府新区万安镇麓山大道二段20号附9号麓山国际3栋2单元2层3号住宅";
|
|
|
|
+ AddressDTO addressDTO = AddressUtil.parseAddress(location);
|
|
|
|
+ String roadAndRoadNumber = AddressUtil.getRoadAndRoadNumber(location);
|
|
|
|
+ System.out.println(roadAndRoadNumber);
|
|
|
|
+ System.out.println(addressDTO);
|
|
|
|
+ String communityNameFromAddress = getCommunityNameFromAddress(location);
|
|
|
|
+ System.out.println(communityNameFromAddress);
|
|
|
|
+ }
|
|
|
|
+}
|