Last active
August 2, 2024 17:15
-
-
Save appkr/ebc95977eeaa8f7d999f0f5ab94df5a9 to your computer and use it in GitHub Desktop.
주소정제기 초벌
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.vroong.neogeo.support.address.refiner; | |
import static com.vroong.neogeo.domain.AdditionalInfo.*; | |
import static com.vroong.neogeo.domain.RegionType.*; | |
import static com.vroong.neogeo.support.address.Regex.*; | |
import com.vroong.neogeo.domain.AddressEntry; | |
import com.vroong.neogeo.domain.AddressEntry.AddressEntryBuilder; | |
import com.vroong.neogeo.domain.Refinable; | |
import com.vroong.neogeo.support.address.Regex; | |
import com.vroong.neogeo.support.address.dictionary.SidoDictionary; | |
import com.vroong.neogeo.support.address.refiner.preprocessor.PreprocessorFactory; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.regex.Matcher; | |
import lombok.Data; | |
import lombok.extern.slf4j.Slf4j; | |
import org.springframework.stereotype.Component; | |
/** | |
* 주소를 정제합니다 | |
* | |
* @see Refinable | |
* @see PreprocessorFactory | |
*/ | |
@Component | |
@Slf4j | |
public class HomemadeAddressRefiner implements Refinable { | |
private String data = ""; | |
private String preprocessed = ""; | |
private Progress progress = new Progress(); | |
public AddressEntryBuilder refine(String uglyAddress) { | |
progress.leave("주소 정제 시작; 원본 주소=" + uglyAddress); | |
this.data = PreprocessorFactory.create(uglyAddress).process(); | |
this.preprocessed = this.data; | |
progress.leave("전처리 완료; 전처리된 주소=" + preprocessed); | |
AddressEntryBuilder builder = AddressEntry.builder() | |
.regionType(RAW); | |
// 가설: 모든 주소는 "시도" 요소를 가지고 있다 | |
// 가설: "시도"는 항상 추출할 수 있다 | |
handleDepth1(builder); | |
// 가설: (세종특별자치시를 제외한) 모든 주소는 "시군구" 요소를 가지고 있다 | |
// 가설: "시군구"는 항상 추출할 수 있다 -> WRONG | |
handleDepth2(builder); | |
if (Regex.isRoadAddress(data)) { | |
handleRoadAddress(builder); | |
} else { | |
handleJibunAddress(builder); | |
} | |
progress.leave("주소 정제 완료; 정제된 주소=" + builder.build().getRawAddress()); | |
if (progress.getStatus() == Status.FAIL) { | |
builder.rawAddress(uglyAddress); | |
} | |
log.info("주소 정제 결과 {}", progress); | |
return builder; | |
} | |
private void handleDepth1(AddressEntryBuilder builder) { | |
String depth1 = ""; | |
Matcher matcher = SIDO_PATTERN.matcher(data); | |
if (matcher.find()) { | |
// "시도"를 추출하고 원본 문자열에서 삭제 | |
depth1 = matcher.group("sido"); | |
data = data.replaceFirst(depth1, "").trim(); | |
depth1 = SidoDictionary.convertSido(depth1); | |
} else { | |
progress.leave("시도 추출 실패; 남은 주소=" + data); | |
progress.fail(); | |
} | |
builder.region1DepthName(depth1.trim()); | |
} | |
private void handleDepth2(AddressEntryBuilder builder) { | |
String depth2 = ""; | |
Matcher matcher = SIGUNGU_PATTERN.matcher(data); | |
if (!builder.build().getRegion1DepthName().contains("세종")) { | |
// "세종(특별자치시)"는 시군구가 없음 | |
if (matcher.find()) { | |
// "시군구"를 추출하고 원본 문자열에서 삭제 | |
depth2 = matcher.group(0); | |
data = data.replaceFirst(depth2, "").trim(); | |
} else { | |
progress.leave("시군구 추출 실패; 남은 주소=" + data); | |
progress.fail(); | |
} | |
} | |
builder.region2DepthName(depth2.trim()); | |
} | |
private void handleRoadAddress(AddressEntryBuilder builder) { | |
// 도로명 주소이면 | |
String captured = "", depth3 = "", depth4 = ""; | |
Matcher matcher = ROAD_NAME_PATTERN.matcher(data); | |
if (matcher.find()) { | |
try { | |
captured = matcher.group(0); | |
if (captured != null) { // e.g. " 까치산로2가길 14" | |
captured = captured.trim(); | |
} | |
final String[] part = captured.split(" "); | |
if (part[0].matches(".*(읍|면)$")) { // e.g. 남원읍 태위로 12-11 | |
depth3 = part[0]; | |
depth4 = part[1]; | |
} else { // e.g. 가작로113번길 1, 통일로 1 | |
depth3 = ""; | |
depth4 = part[0]; | |
} | |
decorateBuildingNumber(builder, matcher); | |
data = data.replaceFirst(captured, "").trim(); | |
} catch (Exception e) { | |
progress.leave("도로명 추출 실패; 남은 주소=" + data); | |
progress.fail(); | |
} | |
} else { | |
progress.leave("도로명 추출 실패; 남은 주소=" + data); | |
progress.fail(); | |
} | |
builder | |
.regionType(ROAD_NAME) | |
.region3DepthName((depth3 != null) ? depth3.trim() : "") | |
.region4DepthName((depth4 != null) ? depth4.trim() : ""); | |
} | |
private void handleJibunAddress(AddressEntryBuilder builder) { | |
// 지번 주소이면 | |
String captured = "", depth3 = "", depth4 = ""; | |
Matcher matcher = JIBUN_PATTERN.matcher(data); | |
if (matcher.find()) { | |
try { | |
captured = matcher.group(0); | |
depth3 = matcher.group("dong"); | |
depth4 = matcher.group("ri"); | |
decorateJibunNumber(builder, matcher); | |
data = data.replaceFirst(captured, "").trim(); | |
} catch (Exception e) { | |
progress.leave("행정동/법정동 추출 실패; 남은 주소=" + data); | |
progress.fail(); | |
} | |
} else { | |
progress.leave("행정동/법정동 추출 실패; 남은 주소=" + data); | |
progress.fail(); | |
} | |
builder | |
.regionType(LEGAL) | |
.region3DepthName((depth3 != null) ? depth3.trim() : "") | |
.region4DepthName((depth4 != null) ? depth4.trim() : ""); | |
} | |
private void decorateBuildingNumber(AddressEntryBuilder builder, Matcher matcher) { | |
String num1 = "", num2 = "", underground = "", air = ""; | |
try { | |
air = matcher.group("air"); | |
underground = matcher.group("underground"); | |
num1 = matcher.group("num1"); | |
num2 = matcher.group("num2"); | |
if (num2 != null && num2.contains("0")) { | |
num2 = ""; | |
} | |
} catch (Exception e) { | |
progress.leave("건물번호 추출 실패; 남은 주소=" + data); | |
progress.fail(); | |
} | |
if (air != null && air.trim().equals("공중")) { | |
builder.additionalInfo(AIR); | |
} | |
if (underground != null && underground.trim().equals("지하")) { | |
builder.additionalInfo(UNDER_GROUND); | |
} | |
builder | |
.mainRegionNumber((num1 != null) ? num1.trim() : "") | |
.subRegionNumber((num2 != null) ? num2.trim() : ""); | |
} | |
private void decorateJibunNumber(AddressEntryBuilder builder, Matcher matcher) { | |
String num1 = "", num2 = "", mountain = ""; | |
try { | |
mountain = matcher.group("mountain"); | |
num1 = matcher.group("num1"); | |
num2 = matcher.group("num2"); | |
if (num2 != null && num2.contains("0")) { | |
num2 = ""; | |
} | |
} catch (Exception e) { | |
progress.leave("지번/건물번호 추출 실패; 남은 주소=" + data); | |
progress.fail(); | |
} | |
if (mountain != null && mountain.trim().equals("산")) { | |
builder.additionalInfo(MOUNTAIN); | |
} | |
builder | |
.mainRegionNumber((num1 != null) ? num1.trim() : "") | |
.subRegionNumber((num2 != null) ? num2.trim() : ""); | |
} | |
enum Status { | |
SUCCESS, FAIL | |
} | |
@Data | |
class Progress { | |
Status status = Status.SUCCESS; | |
List<String> logs = new ArrayList<>(); | |
void fail() { | |
this.status = Status.FAIL; | |
} | |
void leave(String entry) { | |
this.logs.add(entry); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.vroong.neogeo.support.address.refiner; | |
import com.vroong.neogeo.domain.AddressEntry; | |
import lombok.extern.slf4j.Slf4j; | |
import org.junit.jupiter.params.ParameterizedTest; | |
import org.junit.jupiter.params.provider.ArgumentsSource; | |
import static org.junit.jupiter.api.Assertions.assertEquals; | |
@Slf4j | |
class HomemadeAddressRefinerTest { | |
HomemadeAddressRefiner refiner = new HomemadeAddressRefiner(); | |
@ParameterizedTest | |
@ArgumentsSource(UglyAddressProvider.class) | |
public void refine(String ugly, String refined) { | |
final AddressEntry entry = refiner.refine(ugly).build(); | |
log.info("{}", entry); | |
assertEquals(refined, entry.getRawAddress()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.vroong.neogeo.support.address; | |
import java.util.regex.Matcher; | |
import java.util.regex.Pattern; | |
import static java.util.regex.Pattern.MULTILINE; | |
public class Regex { | |
public static boolean isRoadAddress(String query) { | |
// NOTE. 대구광역시 중구 "남성로"는 도로명/동 이름으로 지번과 도로명을 식별할 수 없음; 아래 두 주소는 같은 위치임 | |
// - 도로명: 대구광역시 중구 남성로 35 | |
// - 지번: 대구광역시 중구 남성로 62 | |
if (query.matches(".*\\b(시장북로|세종로)\\b.*")) { | |
return false; | |
} | |
final Matcher matcher = ROAD_NAME_PATTERN.matcher(query); | |
return matcher.find(); | |
} | |
public static boolean isJibunAddress(String query) { | |
if (query.matches(".*\\b(시장북로|세종로)\\b.*")) { | |
return true; | |
} | |
final Matcher matcher = JIBUN_PATTERN.matcher(query); | |
return matcher.find(); | |
} | |
public static final Pattern SIDO_PATTERN = Pattern.compile( | |
"(?<sido>" | |
+ "[가-힣]+도|" // e.g. 경기도, 충청북도 | |
+ "([가-힣]+(?:특별시|광역시|자치시|자치도))|" // e.g. 서울특별시, 대구광역시, 세종특별자치시, 제주특별자치도 | |
+ "(충북|충남|경북|경남|전북|전남|강원|경기|제주)|" | |
+ "(서울|부산|대구|대전|광주|인천|울산|세종)시?" | |
+ ")", MULTILINE); | |
public static final Pattern SIGUNGU_PATTERN = Pattern.compile( | |
"(?<sigungu>" | |
+ ".+시\\s.+구\\b|" // e.g. (경기도) 성남시 중원구 | |
+ ".+시\\b|" // e.g. (충청북도) 청주시 | |
+ ".+구\\b|" // e.g. (서울특별시) 강남구 | |
+ ".+군\\b" // e.g. (대구광역시) 달성군 | |
+ ")", MULTILINE); | |
public static final Pattern ROAD_NAME_PATTERN = Pattern.compile( | |
"(?<road>" | |
+ "계변고개|" // e.g. (울산광역시 중구) 계변고개 | |
+ "[가-힣0-9]+거리\\b|" // e.g. (울산광역시 중구) 만남의거리 | |
+ "[가-힣]+[읍|면]\\s?[가-힣0-9·.]+로\\b|" // e.g. (제주특별자치도 서귀포시) 남원읍 태위로 | |
+ "[가-힣]+[읍|면]\\s?[가-힣0-9·.]+길\\b|" // e.g. (울산광역시 울주군) 산남면 동향교1길 | |
+ "[가-힣0-9·.]+로\\b|" // e.g. (서울특별시 중랑구) 동일로 | |
+ "[가-힣0-9·.]+길\\b" // e.g. (서울특별시 종로구) 경교장1길 | |
+ ")" | |
+ "\\s?" | |
+ "(?<underground>지하|지하 )?" | |
+ "(?<air>공중|공중 )?" | |
+ "(?<num1>[0-9]{1,4})" | |
+ "(?:-)?" | |
+ "(?<num2>[0-9]{1,4})?", MULTILINE); | |
public static final Pattern JIBUN_PATTERN = Pattern.compile( | |
"(?<dong>[가-힣0-9.]+[0-9]{0,2}[읍|면|동|가])" // e.g. (서울특별시 종로구) 종로5가 | |
+ "\\s" | |
+ "(?<ri>[가-힣0-9]+리(?:\\([一-龥]+\\))?)?" // e.g. (경기도 남양주시 화도읍) 녹촌리, (경북 경산시 진량읍) 평사리(平沙) | |
+ "(?:[가-힣a-zA-Z0-9()\\s]*?)?" | |
+ "\\b(?<mountain>산|산 )?" | |
+ "(?<num1>[0-9]{1,4})" | |
+ "(?:-)?" | |
+ "(?<num2>[0-9]{1,4})?\\b", MULTILINE); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class UglyAddressProvider implements ArgumentsProvider { | |
@Override | |
public Stream<? extends Arguments> provideArguments(ExtensionContext context) throws Exception { | |
return Stream.of( | |
// 정상 주소 | |
Arguments.of("세종특별자치시 보람동 738", "세종특별자치시 보람동 738"), | |
Arguments.of("세종특별자치시 금남면 장재리 산24-2", "세종특별자치시 금남면 장재리 산24-2"), | |
Arguments.of("서울특별시 강남구 대치동 890-12", "서울특별시 강남구 대치동 890-12"), | |
Arguments.of("경기도 성남시 중원구 도촌동 200", "경기도 성남시 중원구 도촌동 200"), | |
Arguments.of("제주특별자치도 서귀포시 남원읍 남원리 205-1", "제주특별자치도 서귀포시 남원읍 남원리 205-1"), | |
Arguments.of("경기도 남양주시 화도읍 녹촌리 산52-3", "경기도 남양주시 화도읍 녹촌리 산52-3"), | |
Arguments.of("대구광역시 달성군 논공읍 금포리 1313", "대구광역시 달성군 논공읍 금포리 1313"), | |
Arguments.of("세종특별자치시 남세종로 469", "세종특별자치시 남세종로 469"), | |
Arguments.of("서울 영등포구 영중로 15", "서울특별시 영등포구 영중로 15"), | |
Arguments.of("경기 용인시 수지구 포은대로 552", "경기도 용인시 수지구 포은대로 552"), | |
Arguments.of("제주도 서귀포시 남원읍 태위로 695", "제주특별자치도 서귀포시 남원읍 태위로 695"), | |
Arguments.of("대구광역시 달성군 달성군청로 33", "대구광역시 달성군 달성군청로 33"), | |
Arguments.of("인천광역시 미추홀구 숭의동 190-4", "인천광역시 미추홀구 숭의동 190-4"), | |
Arguments.of("인천광역시 미추홀구 경인로34번길 22", "인천광역시 미추홀구 경인로34번길 22"), | |
Arguments.of("대구광역시 중구 남성로 60", "대구광역시 중구 남성로 60"), // 도로명, 지번 모두 "남성로 60"이 존재하는 경우 | |
Arguments.of("서울특별시 강남구 남부순환로 3104", "서울특별시 강남구 남부순환로 3104"), // 3104와 지하3104 | |
Arguments.of("충청북도 청주시 청원구 오창읍 화산리(花山) 163-2", "충청북도 청주시 청원구 오창읍 화산리(花山) 163-2"), // 한자 포함 | |
Arguments.of("충청북도 청주시 상당구 미원면 기암리(岐岩) 209-6", "충청북도 청주시 상당구 미원면 기암리(岐岩) 209-6"), // 한자 포함 | |
// 도로명 | |
Arguments.of( | |
"경상북도영천시대창면금창로667-1", | |
"경상북도 영천시 대창면 금창로 667-1" | |
), | |
Arguments.of( | |
"울산동구울산 동구 문재2길 28 201호 (방어동,대호미주빌)대호미주빌201 호", | |
"울산광역시 동구 문재2길 28" | |
), | |
Arguments.of( | |
"서울 강서구 염창동 까치산로2가길 14 (뉴파인빌) 101호", | |
"서울특별시 강서구 까치산로2가길 14" | |
), | |
Arguments.of( | |
"울산동구울산 동구 방어진순환도로 1099 1603호 (서부동,신광그린파크)신광그린파크1603 호", | |
"울산광역시 동구 방어진순환도로 1099" | |
), | |
Arguments.of( | |
"울산남구울산 남구 대학로121번길 59 103동 613호 (무거동,무거현대아파트)무거현대아파트103", | |
"울산광역시 남구 대학로121번길 59" | |
), | |
Arguments.of( | |
"경기도안산시한양대학로5 -0 번지 한양대학교 엘지이노텍 안산R층", | |
"경기도 안산시 한양대학로 5" | |
), | |
Arguments.of( | |
"대구 중구 남성로 149 사랑모텔 2층2호", | |
"대구광역시 중구 남성로 149" | |
), | |
Arguments.of( | |
"경기 수원시 팔달구 덕영대로 지하 907-65 수원역지하상가 8호 폰앤폰2", | |
"경기도 수원시 팔달구 덕영대로 지하907-65" | |
), | |
Arguments.of( | |
"충북 청주시 상당구 수영로 328 장자마을현대아파트 204동102호", | |
"충청북도 청주시 상당구 수영로 328" | |
), | |
Arguments.of( | |
"경기도수원시장다리로1 번지 엠하우스1차303 호 엠하우스1차303 호", | |
"경기도 수원시 장다리로 1" | |
), | |
Arguments.of( | |
"경기도성남시정자일로177 -0 번지 인텔리지ⅡB 동3208 호", | |
"경기도 성남시 정자일로 177" | |
), | |
Arguments.of( | |
"경남창원시 성산구경남 창원시 성산구 원이대로 774 509동1006호", | |
"경상남도 창원시 성산구 원이대로 774" | |
), | |
Arguments.of( | |
"충청북도청주시안덕벌로19번길88 -0 번지 우연빌206 호", | |
"충청북도 청주시 안덕벌로19번길 88" | |
), | |
Arguments.of( | |
"경남 김해시 내동 금관대로 1277번길 1-17 2층", | |
"경상남도 김해시 금관대로1277번길 1-17" | |
), | |
Arguments.of( | |
"서울특별시 강동구 천호동 천호대로157길 14번 8층", | |
"서울특별시 강동구 천호대로157길 14" | |
), | |
// 1 SUCCESS, "광주광역시 광산구 월계동"(지번)으로 파싱됨, Kakao geocode FAIL | |
// Cause: 지번으로 인식하고 504를 번지로 잘못 식별함 | |
// Arguments.of( | |
// "광주 광산구 월계동 첨단2차호반아파트 211동 504호 /월계로59호반2차아파트", | |
// "광주광역시 광산구 월계로 59" | |
// ), | |
Arguments.of( | |
"경상남도 창원시 마산회원구 내서읍 숲속로 27 603동1205호", | |
"경상남도 창원시 마산회원구 내서읍 숲속로 27" | |
), | |
Arguments.of( | |
"충청북도 청주시 상당구 중고개로 349 보성트윈힐스아파트 B동 1102호", | |
"충청북도 청주시 상당구 중고개로 349" | |
), | |
Arguments.of( | |
"경기도안산시초지2로 나인호텔67 -13 번지 나인호텔410 호13", | |
"경기도 안산시 초지2로 67-13" | |
), | |
Arguments.of( | |
"서울 구로구 구로동로18길 41 1층 명성지물장식", | |
"서울특별시 구로구 구로동로18길 41" | |
), | |
Arguments.of( | |
"서울특별시 강동구 양재대로 1340 주공아파트 024297206 215동 304호", | |
"서울특별시 강동구 양재대로 1340" | |
), | |
Arguments.of( | |
"서울특별시 구로구 구로중앙로31길 26 3층", | |
"서울특별시 구로구 구로중앙로31길 26" | |
), | |
Arguments.of( | |
"서울특별시 용산구 원효로1가 원효로81길 33 삼성맨션 102호", | |
"서울특별시 용산구 원효로81길 33" | |
), | |
Arguments.of( | |
"경상남도 창원시 마산회원구 내서읍 중리상곡로 18 1동1301호", | |
"경상남도 창원시 마산회원구 내서읍 중리상곡로 18" | |
), | |
// 2 SUCCESS, "서울특별시 송파구 장지동"(지번)으로 파싱됨, Kakao geocode FAIL | |
// Cause: "충민로152" 사이에 공백이 없어서 실패 | |
// Arguments.of( | |
// "서울특별시 송파구 장지동 송파파인타운3단지아파트 306동 206호//충민로152/849번지/", | |
// "서울특별시 송파구 충민로 152" | |
// ), | |
Arguments.of( | |
"경기도 수원시 장안구 조원동 한일타운아파트 108동 2403호/경수대로976번길22", | |
"경기도 수원시 장안구 경수대로976번길 22" | |
), | |
Arguments.of( | |
"서울특별시 동작구 노량진로23가길 16 102동 1603호", | |
"서울특별시 동작구 노량진로23가길 16" | |
), | |
Arguments.of( | |
"서울특별시 강남구 학동로 609 삼익아파트 12동 907호/서울특별시 강남구 청담동 134-21", | |
"서울특별시 강남구 학동로 609" | |
), | |
Arguments.of( | |
"대구광역시달서구달구벌대로1005 -0 번지 (호산동)", | |
"대구광역시 달서구 달구벌대로 1005" | |
), | |
Arguments.of( | |
"경상남도 창원시 마산합포구 3·15대로 90-1", | |
"경상남도 창원시 마산합포구 3·15대로 90-1" | |
), | |
Arguments.of( | |
"부산광역시 남구 용호동 대박타워 201호/동명로170번길56", | |
"부산광역시 남구 동명로170번길 56" | |
), | |
Arguments.of( | |
"경기도 화성시 우정읍 3.1만세로332번길 100-1", | |
"경기도 화성시 우정읍 3.1만세로332번길 100-1" | |
), | |
// 3 FAIL, "서울특별시"까지 파싱됨, Kakao geocode FAIL | |
// Cause: "서울특별시 성동 구서울숲"으로 파싱함 | |
// Arguments.of( | |
// "서울특별시성동구서울숲 2길10 -0 번지 202 호", | |
// "서울특별시 성동구 서울숲2길 10" | |
// ), | |
Arguments.of( | |
"서울 종로구 종로 347 롯데캐슬 천지인 지동 2710호", | |
"서울특별시 종로구 종로 347" | |
), | |
Arguments.of( | |
"서울 영등포구 63로 45 19동 67호", | |
"서울특별시 영등포구 63로 45" | |
), | |
Arguments.of( | |
"경기 화성시 동탄문화센터로 39 포스코더샾 316-1102", | |
"경기도 화성시 동탄문화센터로 39" | |
), | |
Arguments.of( | |
"경기도화성시동탄문화센터로39 -0 번지 동탄시범다은마을포스코더샵317 동1501 호", | |
"경기도 화성시 동탄문화센터로 39" | |
), | |
Arguments.of( | |
"대구 중구 종로 30 3층 이편한고시원 228호", | |
"대구광역시 중구 종로 30" | |
), | |
Arguments.of( | |
"서울 마포구 임정로 47-1 서울 마포구 임정로 47-1 402호", | |
"서울특별시 마포구 임정로 47-1" | |
), | |
Arguments.of( | |
"서울특별시 서초구 사임당로1길 13 서울특별시 서초구 사임당로1길 13/서울특별시 서초구 서초동 1546-3", | |
"서울특별시 서초구 사임당로1길 13" | |
), | |
Arguments.of( | |
"울산광역시 중구 유곡로 77 울산광역시 중구 유곡로 77 선경맨션 101동 1002호/울산광역시 중구 태화동 200-1", | |
"울산광역시 중구 유곡로 77" | |
), | |
Arguments.of( | |
"서울특별시 성동구 동일로 123 성동구 동일로123 (쌍용자동차)/서울특별시 성동구 성수동2가 19-2", | |
"서울특별시 성동구 동일로 123" | |
), | |
Arguments.of( | |
"서울특별시 관악구 남부순환로 1569-5 서울특별시 관악구 남부순환로 1569-5 101/서울특별시 관악구 신림동 1464-46", | |
"서울특별시 관악구 남부순환로 1569-5" | |
), | |
Arguments.of( | |
"서울특별시 동작구 흑석로 84 서울특별시 동작구 흑석로 84 208관 420호/서울특별시 동작구 흑석동 221", | |
"서울특별시 동작구 흑석로 84" | |
), | |
// 4 FAIL, "울산광역시"까지 파싱됨, Kakao geocode OK | |
// Cause: ".+구\b"에서 경계문자때문에 동구를 매칭하지 못함 | |
// Arguments.of( | |
// "울산광역시동구꽃바위 5길27 -0 번지 풍성비치타운1305 호", | |
// "울산광역시 동구 꽃바위5길 27" | |
// ), | |
Arguments.of( | |
"충청남도천안시불당11로82 -0 번지 (불당동,대원칸타빌)607 동1202 호", | |
"충청남도 천안시 불당11로 82" | |
), | |
Arguments.of( | |
"서울특별시 송파구 거여동 거여아파트4단지 402동 1101호/양산로4길8거여4단지아파트", | |
"서울특별시 송파구 양산로4길 8" | |
), | |
Arguments.of( | |
"서울특별시성북구개운사 길 75 -25 번지 Cj international house 층", | |
"서울특별시 성북구 개운사길 75-25" | |
), | |
Arguments.of( | |
"서울특별시종로구인사동길12 -0 번지 (인사동,대일빌딩)", | |
"서울특별시 종로구 인사동길 12" | |
), | |
Arguments.of( | |
"경상남도창원시경남 창원시 마산회원구 내서읍 삼계10길 22 (삼계리,더-푸른아파트) 116동 202호", | |
"경상남도 창원시 마산회원구 내서읍 삼계10길 22" | |
), | |
Arguments.of( | |
"경상남도 창원시 마산회원구 내서읍 삼계10길 22", | |
"경상남도 창원시 마산회원구 내서읍 삼계10길 22" | |
), | |
Arguments.of( | |
"전라남도여수시전남 여수시 쌍봉로 219 202동 402호 (신기동,신기주공)신기주공2단지202 동402 호", | |
"전라남도 여수시 쌍봉로 219" | |
), | |
Arguments.of( | |
"경북 칠곡군 석적읍 동중리10길 20-11 (중리, 경혜빌) 507호", | |
"경상북도 칠곡군 석적읍 동중리10길 20-11" | |
), | |
Arguments.of( | |
"경북 칠곡군 석적읍 서중리7길 15 (남율리, 대교초등학교) 뒷건물 3층 3학년연구실", | |
"경상북도 칠곡군 석적읍 서중리7길 15" | |
), | |
Arguments.of( | |
"경북 칠곡군 석적읍 동중리10길 26-7 (중리) 토담채501호", | |
"경상북도 칠곡군 석적읍 동중리10길 26-7" | |
), | |
Arguments.of( | |
"서울구로구서울 구로구 디지털로31길 85 106동 304호 (구로동,구로두산위브아파트)구로두산위브아파트106 동304 호", | |
"서울특별시 구로구 디지털로31길 85" | |
), | |
Arguments.of( | |
"충북청주시 서원구충북 청주시 서원구 1순환로1137번길 79 914동 1402호 (분평동,주은아파트)주은아파트914 동1402 호", | |
"충청북도 청주시 서원구 1순환로1137번길 79" | |
), | |
Arguments.of( | |
"부산 남구 대연3동 : [상세주소] 대연동 유엔평화로 29번길 137", | |
"부산광역시 남구 유엔평화로29번길 137" | |
), | |
// 5 FAIL, "세종특별자치시 새롬동"(지번)으로 파싱함, Kakao geocode FAIL | |
// Cause: "새롬북로14" 사이에 공백을 넣지 못함 | |
// Arguments.of( | |
// "세종특별자치시 세종특별자치시 새롬동 : [상세주소] 새롬동 새롬북로14 새뜸마을 310동 1205호 ", | |
// "세종특별자치시 새롬북로 14" | |
// ), | |
// 지번 | |
Arguments.of( | |
"울산동구방어동306 -17 번지 휴레지던트405 호", | |
"울산광역시 동구 방어동 306-17" | |
), | |
Arguments.of( | |
"울산남구무거동1464 -9 번지 아름빌201 호", | |
"울산광역시 남구 무거동 1464-9" | |
), | |
Arguments.of( | |
"인천시 옹진군 덕적면 진리 170 -0", | |
"인천광역시 옹진군 덕적면 진리 170" | |
), | |
Arguments.of( | |
"경기안산시 단원구초지동737 -0번지 그린빌주공7단지 115동 111호", | |
"경기도 안산시 단원구 초지동 737" | |
), | |
Arguments.of( | |
"경남창원시 성산구상남동45 -1 번지 성원5단지아파트509동1006호", | |
"경상남도 창원시 성산구 상남동 45-1" | |
), | |
Arguments.of( | |
"경남김해시구산동576 -0 번지 한라비발디아파트111 동904 호", | |
"경상남도 김해시 구산동 576" | |
), | |
// 6 FAIL, "경상북도포항남구송도"로 잘못 파싱함, Kakao geocode OK | |
// Cause: "포항남구"를 "포항시 남구"로 파싱하지 못함 | |
// Arguments.of( | |
// "경상북도포항남구송도동489 -1 번지", | |
// "경상북도 포항시 남구 송도동 489-1" | |
// ), | |
Arguments.of( | |
"부산광역시 부산진구 부전동 503-15 롯데백화점 1층", | |
"부산광역시 부산진구 부전동 503-15" | |
), | |
Arguments.of( | |
"서울특별시 종로구 신문로 1가 58-38 동원빌딩 202", | |
"서울특별시 종로구 신문로1가 58-38" | |
), | |
// 7 FAIL, "경상남도 창원시 마산회원구내서읍 1"로 잘못 파싱함, Kakao geocode FAIL | |
// Cause: "중리338-1" 사이에 공백 없음 | |
// Arguments.of( | |
// "경남창원시 마산회원구내서읍 중리338 -1 번지 현대아파트109 동904 호", | |
// "경상남도 창원시 마산회원구 내서읍 중리 338-1" | |
// ), | |
// 8 FAIL, "경상남도 창원시마산회원구 내서읍 1"로 잘못 파싱함, Kakao geocode FAIL | |
// Cause: "중리338-1" 사이에 공백 없음 | |
// Arguments.of( | |
// "경상남도창원시마산회원구 내서읍 중리338 -1 번지 현대아파트104 동803 호", | |
// "경상남도 창원시 마산회원구 내서읍 중리 338-1" | |
// ), | |
Arguments.of( | |
"서울특별시강남구서울 강남구 신사동 555-32", | |
"서울특별시 강남구 신사동 555-32" | |
), | |
Arguments.of( | |
"부산 부산진구 범천2동 산 44-147 단독주택", | |
"부산광역시 부산진구 범천2동 산44-147" | |
), | |
// 9 SUCCESS, "서울특별시 중랑구 면목본동 101"로 잘못 파싱함 | |
// Cause: "1526남청파인힐아파트" 사이에 공백 없음 | |
// Arguments.of( | |
// "서울특별시 중랑구 면목본동 1526남청파인힐아파트 101 606호", | |
// "서울특별시 중랑구 면목본동 1526" | |
// ), | |
Arguments.of( | |
"서울시 중랑구 면목본동 1199번지2층", | |
"서울특별시 중랑구 면목본동 1199" | |
), | |
Arguments.of( | |
"경상북도 경산시 하양읍 부호리 391-2 다정하숙 A동 304호", | |
"경상북도 경산시 하양읍 부호리 391-2" | |
), | |
// 10 FAIL, "전라남도 목포 죽교동 582-73"으로 잘못 파싱함, Kakao geocode OK | |
// Cause: "목포"를 "목포시"로 파싱하지 못함 | |
// Arguments.of( | |
// "전라남도 목포죽교동 582-73", | |
// "전라남도 목포시 죽교동 582-73" | |
// ), | |
Arguments.of( | |
"대전광역시 서구 갈마1동 코아건축적산 263-29 203호", | |
"대전광역시 서구 갈마1동 263-29" | |
), | |
Arguments.of( | |
"경기도 안산시 단원구 와동 (와동) 강서팰리스 825-4번지 강서팰리스401호", | |
"경기도 안산시 단원구 와동 825-4" | |
), | |
// 11 SUCCESS, "부산광역시 해운대구광역시 좌동 1473-1"로 잘못 파싱됨 | |
// Cause: depth2를 "해운대구광역시"로 잘못 파싱함 | |
// Arguments.of( | |
// "부산광역시 해운대구광역시 좌동 1473-1 대림아크로텔 2033호//", | |
// "부산광역시 해운대구 좌동 1473-1" | |
// ), | |
Arguments.of( | |
"서울특별시 마포구 창전동 443 해모로아파트 01053110711 105동 1603호", | |
"서울특별시 마포구 창전동 443" | |
), | |
Arguments.of( | |
"서울특별시 강남구 삼성동 141 성원빌딩 지하1층 지하철연결통로로 오셔서 전화주세요/01022580009 4층", | |
"서울특별시 강남구 삼성동 141" | |
), | |
Arguments.of( | |
"충청북도 청주시 상당구 금천동 287 실주소 //남문로 1가 53 트레비앙 1202호", | |
"충청북도 청주시 상당구 금천동 287" | |
), | |
// 12 FAIL, "경기도"까지 추출 | |
// Cause: 번지를 "1781-78"로 잘못 파싱함 | |
// Arguments.of( | |
// "경기도부천시중동178178 번지 위브더스테이트 1109-2 위브더스테이트 301동 1702 층", | |
// "경기도 부천시 중동 178" | |
// ), | |
Arguments.of( | |
"서울마포구창전동6 -29 번지 404 호", | |
"서울특별시 마포구 창전동 6-29" | |
), | |
Arguments.of( | |
"서울특별시 강동구 성내동 244-3 * 길동점 매장요청빌 실주소:길동 410-1 302호", | |
"서울특별시 강동구 성내동 244-3" | |
), | |
Arguments.of( | |
"부산 부산진구 부암동 부산서면 동문굿모닝힐 735-0 101동 505호", | |
"부산광역시 부산진구 부암동 735" | |
), | |
Arguments.of( | |
"대구광역시 서구 비산2.3동 2311 01028014911 2층", | |
"대구광역시 서구 비산2.3동 2311" | |
), | |
Arguments.of( | |
"충청북도 충주시 칠금.금릉동 1015 부영2차아파트203-605", | |
"충청북도 충주시 칠금.금릉동 1015" | |
), | |
Arguments.of( | |
"경기고양시 일산서구대화동2267 -2 번지 /호수로856번길 56-30 3층 층", | |
"경기도 고양시 일산서구 호수로856번길 56" | |
), | |
Arguments.of( | |
"서울특별시 용산구 한강로2가 98-3 태화빌딩 한강로2가98-2 301호", | |
"서울특별시 용산구 한강로2가 98-3" | |
), | |
Arguments.of( | |
"서울특별시 구로구 구로동 98-7 해담채 1401호/구로중앙로18길31", | |
"서울특별시 구로구 구로중앙로18길 31" | |
), | |
Arguments.of( | |
"경기도 수원시 장안구 송죽동 (송죽동) 월드타워 5층 501-1호", | |
"경기도 수원시 장안구 송죽동 501-1" | |
), | |
Arguments.of( | |
"서울특별시 마포구 중동 129 -가우디빌라 601호", | |
"서울특별시 마포구 중동 129" | |
), | |
Arguments.of( | |
"경기 안산시 단원구 고잔동 무진빌라3차 661-2 103동404호", | |
"경기도 안산시 단원구 고잔동 661-2" | |
), | |
// SUCCESS, | |
// TODO @appkr "2773 -202호"에서 -202가 떨어진 이유 | |
// Arguments.of( | |
// "충청북도 청주시 흥덕구 복대동 2773 -202호 #123456", | |
// "충청북도 청주시 흥덕구 복대동 2773-202" | |
// ), | |
Arguments.of( | |
"충청남도 천안시 동남구 신부동 776 챌로202", | |
"충청남도 천안시 동남구 신부동 776" | |
), | |
Arguments.of( | |
"서울특별시 구로구 구로동 611-26 오퍼스1 511호/구로중앙로207", | |
"서울특별시 구로구 구로동 611-26" | |
), | |
Arguments.of( | |
"서울특별시 용산구 이촌동 오퍼스1 300-322 (국제부동산)", | |
"서울특별시 용산구 이촌동 300-322" | |
), | |
Arguments.of( | |
"서울특별시 서대문구 미근동 215 충정로3가189-8 미동아파트810", | |
"서울특별시 서대문구 미근동 215" | |
), | |
Arguments.of( | |
"서울특별시성동구성수1가2동656 -681 번지", | |
"서울특별시 성동구 성수1가2동 656-681" | |
), | |
Arguments.of( | |
"부산광역시동래구부산 동래구 수안동 268-27", | |
"부산광역시 동래구 수안동 268-27" | |
), | |
Arguments.of( | |
"광주광역시북구광주 북구 신안동 225-5 베르디움", | |
"광주광역시 북구 신안동 225-5" | |
), | |
Arguments.of( | |
"전라남도여수시전남 여수시 학동 20-19", | |
"전라남도 여수시 학동 20-19" | |
), | |
Arguments.of( | |
"서울특별시 중랑구 면목3.8동 5-3 무지개빌라 403호", | |
"서울특별시 중랑구 면목3.8동 5-3" | |
), | |
Arguments.of( | |
"서울 구로구 구로동 429-156 구로2동 429-156번지 3층", | |
"서울특별시 구로구 구로동 429-156" | |
), | |
Arguments.of( | |
"경기 안산시 단원구 선부동 공작한양아파트 121동 1085-0 121동 1202호", | |
"경기도 안산시 단원구 선부동 1085" | |
), | |
// 13 FAIL, "서울특별시"까지 파싱됨 | |
// Cause: "호"가 떨어지면서, 30261로 전처리되었고, 다시 3026-1로 잘못 파싱됨 | |
// Arguments.of( | |
// "서울특별시서초구잠원동 한신아파트 11차 320동 302호61 -0 번지 신반포한신아파트320 동302 호", | |
// "서울특별시 서초구 잠원동 61" | |
// ), | |
Arguments.of( | |
"서울특별시 중랑구 면목3.8동 30-21 101호", | |
"서울특별시 중랑구 면목3.8동 30-21" | |
), | |
Arguments.of( | |
"서울특별시 강동구 천호2동 339-12 호 201호", | |
"서울특별시 강동구 천호2동 339-12" | |
), | |
Arguments.of( | |
"서울특별시서초구잠원 동 41 -0 번지 1층 층102 호", | |
"서울특별시 서초구 잠원동 41" | |
), | |
Arguments.of( | |
"대구 수성구 황금동 캐슬골드파크5단지 369-0 1506-1703", | |
"대구광역시 수성구 황금동 369" | |
), | |
Arguments.of( | |
"서울 송파구 잠실동 잠실주공5단지아파트 521동 27-0 521동1102호", | |
"서울특별시 송파구 잠실동 27" | |
), | |
Arguments.of( | |
"충청남도천안시쌍용동 주공9단지65 -0 번지 주공9단지아파트404 동704 호", | |
"충청남도 천안시 쌍용동 65" | |
), | |
Arguments.of( | |
"서울 서초구 반포1동 : [상세주소] 반포동 717-13번지 B01호", | |
"서울특별시 서초구 반포1동 717-13" | |
), | |
Arguments.of( | |
"광주 북구 문흥1동 : [상세주소] 문흥동 186-12번지 203호", | |
"광주광역시 북구 문흥1동 186-12" | |
), | |
// 14 SUCCESS, "서울특별시 관악구 신림동 구 신림5동 1433-55"로 잘못 파싱됨, Kakao geocode FAIL | |
// Cause: 괄호 때문에 PatternSyntaxException 발생 | |
// Arguments.of( | |
// "서울 관악구 신림동 (구 신림5동) : [상세주소] 신림동 1433-55 프라비다트라움 1006호", | |
// "서울특별시 관악구 신림동 1433-55" | |
// ), | |
Arguments.of( | |
"경상남도 사천시 정동면 고읍리 469-1 대흥그랜저맨션 다동1108호 16층", | |
"경상남도 사천시 정동면 고읍리 469-1" | |
), | |
Arguments.of( | |
"대구광역시 달성군 유가읍 쌍계리 633 대구테크노폴리스중흥에스-클래스포디움 1306동 602호", | |
"대구광역시 달성군 유가읍 쌍계리 633" | |
), | |
Arguments.of( | |
"경기도 하남시 망월동 1162 미사강변 골든 센트로(GOLDEN CENTRO) 2802-1302", | |
"경기도 하남시 망월동 1162" | |
), | |
// SUCCESS, "(平沙)" 한자 빠짐, Kakao geocode WRONG COORDS | |
Arguments.of( | |
"경북 경산시 진량읍 평사리(平沙) 69 1동1호(지하)", | |
"경상북도 경산시 진량읍 평사리(平沙) 69" | |
), | |
// SUCCESS, "(坪沙)" 한자 빠짐, Kakao geocode OK | |
Arguments.of( | |
"경북 경산시 진량읍 평사리(坪沙) 69 1동1호(지하)", | |
"경상북도 경산시 진량읍 평사리(坪沙) 69" | |
), | |
// 15 SUCCESS | |
// Cause: "장재리"가 누락됨 | |
// Arguments.of( | |
// "충청남도 아산시 배방읍 (배방읍) 장재리 1690 202호 읍읍 (읍읍) 배방1읍 (배방1읍)", | |
// "충청남도 아산시 배방읍 장재리 1690" | |
// ), | |
Arguments.of( | |
"울산광역시 남구 신정동 1890 문수로2차아이파크2단지 204동 1203호", | |
"울산광역시 남구 신정동 1890" | |
) | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
// 도로명
https://regex101.com/r/RUYDwq/1
// 지번
https://regex101.com/r/6jGoxw/1