Java 정규식에서 subgroup 값 가져오기
Facebook 스프링사용자 모임에 질문이 올라왔다. 아래 코드가 의도와 다른 결과를 뱉는다는 질문이다.
웹에서 정규식을 테스트할수 있는 사이트인 regex101 에서는 정상 작동한다는 말까지 첨부하셧다
1
2
3
4
5
6
7
8
private static final Pattern SIDO_PATTERN = Pattern.compile(
"(?<sido>\n" +
" ([가-힣]+도)|\n" +
" ([가-힣]+(특별시|광역시|자치시|자치도))|\n" +
" (충북|충남|경북|경남|전북|전남|강원|경기|제주|서울|부산|대구|대전|광주|인천|울산|세종|제주)\n" +
")\\s");
SIDO_PATTERN.matcher("서울특별시 강남구 대치동 890-12").matches(); // false
SIDO_PATTERN.matcher("서울특별시 강남구 대치동 890-12").group("sido"); // Match not found
보통 이런경우면 언어마다 미묘하게 다른 정규식 문법의 문제인데… 이번 케이스는 그런것과 좀 다른 특이한 케이스라 혹시 궁금하실분이 있을가봐 정리해둔다
- 문제1. 정규식 패턴에 임의로 \n을 넣으면 안된다.
- 당연하다면 당연하지만 정규식 패턴에 \n이 들어가 있으면 해당 값도 패턴의 일부로 인식된다. 코드 복붙하다 들어간 것 같은데 정확히 넣었어야 했다
- 문제2. 자바는 Matching 체크와, SubMatching(용어 맞나?)이 구별되어있다
- matches를 호출하였는데 다른 언어와 다르게 java는 패턴을 한번 먹인다고 모든 작업이 끝나질 않는다. matches는 전체 패턴이 매칭되었는지를 체크하는 함수고, 특정 그룹을 갖고오고 싶다면 lookingAt 을 호출하여 subgroup 의 파싱을 해 줘야 그 다음으로 group 함수를 사용할 수 있게 된다
수정한 코드는 다음과 같다
1
2
3
4
5
6
7
8
9
10
public class TestClass {
public static void main(String[] args) {
var matcher = SIDO_PATTERN.matcher("서울특별시 강남구 대치동 890-12");
matcher.lookingAt();
System.out.println(matcher.group("sido"));
}
private static final Pattern SIDO_PATTERN = Pattern.compile(
"(?<sido>([가-힣]+도)|([가-힣]+(특별시|광역시|자치시|자치도))|(충북|충남|경북|경남|전북|전남|강원|경기|제주|서울|부산|대구|대전|광주|인천|울산|세종|제주)\\s)");
}
결과
This post is licensed under CC BY 4.0 by the author.