자바 Matcher와 IllegalStateException(No match available)
자바 jpa소스를 공부하던 중에 Matcher의 IllegalStateException(No match available)이 발생했다.

Pattern NESTED_PROPERTY_PATTERN = Pattern.compile("\\p{Lu}[\\p{Ll}\\p{Nd}]*$");
위와 같은 패턴을 이용하여 entity의 attribute를 찾는 로직인데, 위 로직은 어려우니 아래처럼 간단한 숫자 정규식으로 테스트를 해보았다.
String word = "12a34b";
Pattern pattern = Pattern.compile("[0-9]");
Matcher matcher = pattern.matcher(word);
위 정규식은 숫자를 의미하는 정규식과 테스트할글자이다.
위 경우에서 matcher.find()를 실행하면 어떤 값이 나올까?
모두가 예상하겠지만 true가 나온다.
그렇다면 matcher.start()를 실행하면 어떤 값이 나올까?
이것 또한 쉽다. 첫번째로 시작하는 인덱스를 리턴하니까, 0이라는 값이 리턴될 것 이다.


위 코드는 아무런 문제가 없다.
그렇다면, 아래와 같은 코드를 다시 실행해보자.
어떠한 결과가 나올까?

위의 코드와 똑같은 코드니 당연히 숫자가 처음 시작하는 인덱스 값인 0이 나와야할 것 같다.
하지만.....두둥!! 에러가 발생했다.

분명 예상한 결과 값 0이 나와야할 것 같은데...에러가 발생했다.
그렇다면 start()메소드를 들어가보자.

first라는 변수가 0보다 작을 때 위와같은 에러가 발생한다.
그렇다면 Matcher라는 객체를 생성할때는 위의 변수에 값을 세팅해주지 않는다는 것이고, 결국 어떠한 메소드가 Matcher안의 여러가지 변수들을 세팅해준다는 얘기가 되는 것이다.
그렇다면 다시 처음으로 돌아가서, 에러가 나지 않은 상황을 생각해보자.
Matcher객체 생성 후 find() -> start() 위와 같은 순서로 호출을 했다.
그렇다면 find메소드를 들어가보자.

음...여기도 first에 값을 세팅해주는 로직은 보이지 않는다.
그렇다면 search로 한번 더 들어가보자.

드디어 찾았다. first에 from이라는 값을 세팅해주는 로직이 보인다.
참고로 first의 기본 값은 -1, from의 기본값은 0이다.


정리하면 Matcher객체는 생성 후에 find라는 메소드를 실행시켜야, start(), group()등 해당객체에서 제공하는 함수를 사용할 수 있는 것이다.
또한 find메소드는 호출 할 때마다 대상 객체를 계속 순회하면서 값을 갱신한다.
따라서 아래와 같은 코드를 만들어 계속적으로 값을 찾을 수 있다.


무엇인가 iterator와 같은 객체를 제공해주는 것이 있을 것 같기도한데, 이번 포스팅의 목적은 find메소드를 실행했을때 에러가 발생한 것에 대한 기록이기 때문에, Macher객체에 대한 자세한 조사는 하지 않았다.
암튼 jpa소스를 분석하면서, Matcher객체에 대하여 새로운 사실을 알게되었다. 엄청나게 대단한 거나 어려운것은 아니지만, 기록을 위하여 포스팅해둔다.
* 개발하면서 경험한 것들을 가볍게 기록하는 블로기이기 때문에, 잘못된 정보가 있다면 언제든지 댓글 부탁드리겠습니다.