티스토리 뷰
최근 외근이 잦아서, 포스팅을 할 여유가 없었네요...
저번 작업에 이어서, 여러가지 문제점이 파악돼서 조금 제대로 정리도 할겸 다시 정규식을 작성하려합니다.
저번에 사용된 정규식은 아래와 같습니다.
String addReg1 = "(([가-힣]|\\d)+(동))+(([가-힣]|\\d)+(호))" +
"|([가-힣]+(아파트))" +
"|([가-힣])+(구)+([가-힣])+(동)";
위와 같이 작성한 정규식에서 대표적으로 문제가 발생한 부분은 일단 공백을 인식 못했습니다. 거기에 더불어서 제대로 된 처리가 안되어있어서 인식 정확도가 많이 떨어졌습니다. 저대로 프로젝트에 적용했다면, 거의 100% 확률로 컴플레인이 들어올거 같았습니다.
그래서 정규식을 수정하게 됐는데 일단 결과물은 아래와 같습니다.
String addReg1 = "(([가-힣A-Za-z·\\d~\\-\\.]{2,}(로|길).[\\d]+)" +
"|([가-힣A-Za-z·\\d~\\-\\.]+(읍|동|번지)\\s)[\\d]+)" +
"|([가-힣A-Za-z]+(구)+\\s*[가-힣A-Za-z]+(동))"+
"|([가-힣a-zA-Z\\d]+(아파트|빌라|빌딩|마을))";
하나 씩 살펴볼까요? 일단 처음으로 도로명 주소도 사용하는경우가 많아서 도로명 주소도 마스킹 처리 할 수 있도록 아래와 같은 패턴을 추가했습니다.
(([가-힣A-Za-z·\\d~\\-\\.]{2,}(로|길).[\\d]+)
마찬가지로 읍/동/번지도 탐색이 가능하도록 아래와 같이 패턴을 or처리 했습니다.
([가-힣A-Za-z·\\d~\\-\\.]+(읍|동|번지)\\s)[\\d]+)
그리고 금천구 가산동 같은 구와 동도 마스킹처리가 필요해 아래와 같은 정규식을 추가했습니다.
([가-힣A-Za-z]+(구)+\\s*[가-힣A-Za-z]+(동))
그리고 추가적으로 아파트와 빌라 빌딩등의 이름도 마스킹 처리가 필요해 아래와 같은 정규식을 1차적으로 작성완료 했어요.
([가-힣a-zA-Z\\d]+(아파트|빌라|빌딩))
다음으로는 저번시간과 크게 다르지 않게 Compile을 하고 Matcher를 선언했습니다.
Pattern pattern1 = Pattern.compile(addReg1);
Matcher matcher1 = pattern1.matcher(address);
마찬가지로 수정된 정규식에 맞게 ReplaceAll 함수를 실행시켰습니다.
while (matcher1.find()){
String replaceAddress;
replaceAddress = matcher1.group().replaceAll("[^동호구아파트빌라딩길시마을\\-\\s]","*");
address = address.replace(matcher1.group(),replaceAddress);
}
사실 여기까지 진행했을 때 결과는 매끄러웠습니다. 마스킹도 원하던 대로 잘 되고 있다고 생각이 들어서, 여기서 조금만 보완하면 되겠다고 생각을 했었습니다. 그런데 생각해보니 한가지 문제점이 있었습니다.
먼저 아래와 같은 주소지를 마스킹 처리한다고 했을 때
서울특별시 마포구 동안동 521-32번지 501호
결과는 아래와 같습니다. 근데 완벽하게 마스킹 처리가 되지 않고 있고, 뭔가 엉성합니다.
서울특별시 마*구 동*동 ***-**** ***호
제가 원하던 결과값은 아래와 같이 깔끔한 마스킹처리 였습니다.
서울특별시 **구 **동 ***-**** ***호
원인은 replace문에서 모든 문자를 한글자씩 매치시켜서 바꾸다보니, 중복단어에 대해서는 미처 대비하지 못했습니다.
replaceAddress = matcher1.group().replaceAll("[^동호구아파트빌라딩길시마을\\-\\s]","*");
물론 이대로 진행해도 대부분의 경우에는 문제가 없겠지만, 특수한 경우에는 모든 구와 동이 노출될 수도 있었습니다. 그래서 이런 문제를 방지하기 위해서 일단 패턴을 세분화하는 작업부터 진행했습니다.
먼저 관련한 문제가 가장 많이 일어날만한 패턴인 ~구~동 형식만 다른 패턴으로 만들었습니다.
String addReg2 = "([가-힣A-Za-z]+(구)+\\s*[가-힣A-Za-z]+(동))";
그리고 아래와 같은 패턴으로 바꿨습니다.
replaceAddress = matcher2.group().replaceAll("[^구동\\s]","*");
이제 근본적인 문제인 구/동을 전부 바꾸는 문제점을 해결하려합니다.
처음으로 생각한 해결방안은 공백을 기준으로 문자를 나눠서 변경하는 방식이었는데, 이 방식은 모든 문서에 적용되지 않았습니다. 텍스트가 일렬로 붙어있는 경우도 있었기 때문입니다. 그래서 결국 합의점으로 문자수에 맞춰서 마스킹이 아니라 전체 텍스트를 마스킹하는 방향으로 틀었습니다.
정말 아쉬웠지만, 현재로서는 이게 최선이였습니다.
replaceAddress = matcher2.group().replaceAll("([가-힣A-Za-z]+(구)+\\s*[가-힣A-Za-z]+(동))","**구 **동");
그리고 조금 간소화시킨 패턴을 하나 더 생성시켰습니다.
String addReg1 = "([\\d~\\-\\.]{2,}(동).[\\d]+)";
이렇게 된다면 101동 101호 같이 숫자로 된 동과 호는 모두 잡을 수 있습니다. 그리고 해당 패턴은 특정 지을 수 있어서 원하는 부분만 마스킹 처리가 가능했습니다.
while (matcher1.find()){
String replaceAddress;
replaceAddress = matcher1.group().replaceAll("[^동\\s]","*");
address = address.replace(matcher1.group(),replaceAddress);
}
그럼 이쯤에서 한번 테스트 해볼려 합니다.
#테스트 주소지
경기도 도민시 당당구 두남동 두리원마을 1단지아파트 101동 101호
#테스트 결과
경기도 도민시 **구 **동 두리원마을 1단지아파트 ***동 ***호
아직 손봐야할 부분이 보이지만 나름대로 원하는 패턴값이 추출된 거 같습니다.
이제 아파트 부분이 신경쓰이네요. 해당 부분을 수정하려합니다. 정규식을 하나 추가한 뒤에
String addReg2 = "([가-힣a-zA-Z\\d~\\-\\.]+(아파트|빌라|빌딩|마을))";
해당 부분을 if문을 사용해서 변경해줍니다.
while (matcher2.find()){
String replaceAddress = null;
try{
if(matcher2.group().contains("아파트")){
replaceAddress = matcher2.group().replaceAll("[가-힣a-zA-Z\\d]+(아파트)","**아파트");
}
if(matcher2.group().contains("빌라")){
replaceAddress = matcher2.group().replaceAll("[가-힣a-zA-Z\\d]+(빌라)","**빌라");
}
if(matcher2.group().contains("빌딩")){
replaceAddress = matcher2.group().replaceAll("[가-힣a-zA-Z\\d]+(빌딩)","**빌딩");
}
if(matcher2.group().contains("마을")){
replaceAddress = matcher2.group().replaceAll("[가-힣a-zA-Z\\d]+(마을)","**마을");
}
address = address.replace(matcher2.group(),replaceAddress);
}catch (Exception e){
e.printStackTrace();
}
}
그 뒤에 다시 검색해 봤습니다. 아주 잘나오네요
경기도 도민시 **구 **동 **마을 **아파트 ***동 ***호
다만 이 방식은 텍스트가 공백이 없으면 문제가 발생합니다.
만약 이런 텍스트가 있다고 가정해볼게요.
문서마다 특징이 다르기 때문에 Trim(공백제거) 처리가 되어 있는 경우도 생겼습니다.
경기도도민시당당구두남동두리원마을1단지아파트101동101호
이런경우 마스킹 처리가 어떻게 될까요?
*******구**동**마을**아파트***동***호
정규식은 $구$동으로 잡히기 때문에 공백이 없을경우 앞에있는 부분까지 잡히게 됩니다. 그리고 저는 필요없는 부분까지는 마스킹이 필요없다고 생각했어요. 사실 전부 마스킹 처리 할 것이라면, 그냥 정규식에 잡히는대로 별처리를 하면 그만이니까요.
그래서 대안을 생각해내야 했습니다.
대안 1 ) 글자수 제한 특정 구간에서 2글자까지 ( Ex: 서울특별시마포구 > 서울특별시**구)
> 특정 구 이름이 두글자가 아닌경우도 있음 (EX: 중구,서구,북구)
대안 2 ) 정규식에서 시는 제외시켜 매치( 서울특별시마포구 > 마포구 매치)
> 만약 시로 시작하는 구이름이 있다면?
'웹 프로그래밍 > JAVA' 카테고리의 다른 글
[Java] 문자열 출력하기 - Hello World! (1) | 2022.08.22 |
---|---|
[JAVA] 주소지 마스킹 처리 (0) | 2022.05.17 |
Class상속의 이해2 + 오버라이딩 (0) | 2021.02.27 |
Class의 상속관계(JAVA) (0) | 2021.02.27 |
3차원배열을 활용한 반 점수 출력 (0) | 2021.02.02 |
- Total
- Today
- Yesterday
- JWT
- Spring + ELK
- producer
- elasticSearch
- consumer
- rabbitmq
- 오늘저녁 삼겹살
- Gateway
- Kafka Connect
- config
- github
- git
- UserService
- Logstash to ElasticSearch
- 미래의나에게동기부여
- MSA
- LoadBalancer
- zipkin
- ACTUATOR
- Logstash 활용
- prometheus
- 운동
- 루틴기록
- Feign
- springcloud
- MariaDB
- docker
- kafka
- 운동일기
- 빅-오
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |