본문 바로가기

Programming/Java

[Java] Pattern, Matcher Class 사용법과 메소드 정리

자바에서는 정규식을 활용해 문자열을 검증, 탐색을 돕는 Pattern, Matcher 클래스를 제공해준다.

다음에도 쉽게 활용할 수 있도록 정리하려고 한다.

 

👨‍🏫 클래스 분석

Pattern

정규 표현식이 컴파일된 클래스. 정규 표현식에 대상 문자열을 검증하거나, 활용하기 위해 사용되는 클래스이다. 

주요 메소드

static Pattern compile(String regex) 주어진 정규식을 갖는 패턴을 생성
String pattern() 컴파일된 정규 표현식을 반환
Matcher matcher(CharSequence input) 패턴에 매칭할 문자열을 입력해 Matcher를 생성
static boolean matches(String regex, CharSequence input) 정규식과 문자열이 일치하는지 확인
String[] split(CharSequence input)
String[] split(CharSequence input, int limit)
패턴이 일치하는 항목을 중심으로 input을 분할

limit - 1의 횟수만큼 패턴 일치를 시켜 문자열을 자름(문자열이 limit개 생성)
만약 0이하라면 최대한 많이 적용

 

Matcher

Pattern클래스를 받아 대상 문자열과 패턴이 일치하는 부분을 찾거나 전체 일치 여부 등을 판별하기 위해 사용된다. 

주요 메소드

Pattern pattern() matcher가 해석한 패턴을 반환
Matcher usePattern(Pattern newPattern) matcher가 사용할 Pattern을 변경
Matcher reset(CharSequence input) matcher가 분석할 문자열을 변경
int start() 매칭하는 문자열의 시작 인덱스를 반환
int start(int group) 매칭 문자열 중 group번째 문자열의 시작 인덱스를 반환
0은 그룹의 전체 패턴을 의미 start(0) = start()
int start(String name) 매칭 문자열 중 해당 name을 지정한 그룹의 시작 인덱스를 반환
int end() 일치하는 문자열의 마지막 문자열 이후 인덱스를 반환
int end(int group) 매칭 문자열 중 group번째 그룹의 마지막 문자열 이후(+1) 인덱스를 반환
0은 그룹의 전체 패턴을 의미 end(0) = end()
int end(String name) 매칭 문자열 중 해당 name을 지정한 그룹의 마지막 문자열 이후(+1) 인덱스를 반환
String group() 매치와 일치하는 문자열을 반환
String group(int group) 매칭되는 문자열 중 group번째 그룹의 문자열 반환
0은 그룹의 전체 패턴을 의미 group(0) = group()
String group(String name) 매칭되는 문자열 중 해당 name을 지정한 그룹의 문자열 반환
int groupCount() 패턴 내에 그룹핑한 개수를 반환(패턴에 있는 괄호 개수)
boolean matches() 패턴에 전체 문자열이 일치한 경우 true를 반환
boolean find() 패턴이 일치하는 다음 문자열을 찾는다
다음 문자열이 있다면 true
boolean find(int start) start 인덱스 이후부터 패턴에 일치하는 문자열을 찾는다
String replaceAll(String replacement) 패턴과 일치하는 모든 문자열을 지정된 replacement로 변경




 

👩‍💻 이해 & 활용하기

1️⃣ 생성하기, 정규식 일치여부 판별하기

Pattern 클래스는 Pattern.compile(regex)를 통해 생성할 수 있고, 컴파일된 패턴을 사용하는 Matcher는 만들어진 객체에 matcher(input) 메소드를 사용해 생성한다.

 

String regex = "^[a-zA-Z]$"; // 영문자만 존재하는가?
String input = "Test String";

System.out.println(Pattern.matches(regex, input)); // false

Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);

System.out.println(matcher.matches());// false

제일 기본적으로 사용할 수 있는 메소드는 Pattern.matches(regex, input)Matcher.matches()이다. 두 메소드 모두 주어진 문자열이 패턴에 맞는지 판별하는 메소드이다. 주어진 문자열에서는 공백이 포함되었기 때문에 false가 반환된다.

 

2️⃣ Grouping

예시) 프로그래머스 - 2018 KAKAO BLIND RECRUITMENT [1차] 다트게임 사용(🔗 링크)

 

Matcher에 주어진 input 문자열을 패턴에 맞는지 확인하거나 패턴과 일치하는 문자열을 반복해 추출할 수 있는데, 이때 find() 메소드와 group() 메소드가 사용된다. find() 메소드는 패턴이 일치하는 다음 문자열이 존재한다면 true를 반환하기 때문에 while문을 통해 문자열의 끝까지 조회가 가능하다

Pattern pattern = Pattern.compile("([0-9]+)([SDT])([*#]?)");
Matcher matcher = pattern.matcher("1D2S#10S*");

while(matcher.find()){
  System.out.println(matcher.group());
}
// 1D
// 2S#
// 10S*

 

 

출력을 확인해보면 위와 같이 문자열이 분리되는 것을 알 수 있다. find()를 통해 찾은 문자열에서 start(), end(), group() 메소드를 추가적으로 활용할 수 있다.

 

 

패턴의 그룹은 소괄호()를 기준으로 지정되는데 예제의 정규식에서는 위와같이 분리되는 것을 알 수 있다. 

 

 

while (matcher.find()) {
  System.out.println(matcher.group(1) + "/" + matcher.group(2) + "/" + matcher.group(3));
  System.out.println(matcher.start(1) + "/" + matcher.start(2) + "/" + matcher.start(3));
  System.out.println(matcher.end(1) + "/" + matcher.end(2) + "/" + matcher.end(3));
  System.out.println();
}
/* 출력
1/D/
0/1/2
1/2/2

2/S/#
2/3/4
3/4/5

10/S/*
5/7/8
7/8/9
*/

이를 통해 메소드를 다시 한 번 이해 해보면,

group(int i)는 i번째 그룹의 문자열,

start(int i)는 i번째 그룹의 문자열의 시작 인덱스,

end(int t)는 i번째 그룹의 문자열의 종료 인덱스 + 1의 값을 반환하는 것을 알 수 있다!

 

 

만약 그룹을 숫자로 매번 사용하기 어렵다면 각 그룹마다 이름을 붙일 수 있다. 각 그룹에 ?<'name'>을 통해 이름을 지정하면 group(), start(), end() 등의 함수에서 순서를 외울 필요 없이 이름으로 접근이 가능해진다.

Pattern pattern = Pattern.compile("(?<score>[0-9]+)(?<bonus>[SDT])(?<option>[*#]?)");
Matcher matcher = pattern.matcher("1D2S#10S*");

while(matcher.find()){
  System.out.println(matcher.group("score"));
}
// 1
// 2
// 10

 

 

 

 

 


📚 Reference

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/regex/Matcher.html
https://docs.oracle.com/javase/9/docs/api/java/util/regex/Pattern.html

 

'Programming > Java' 카테고리의 다른 글

[Java] 어노테이션(Annotation)  (0) 2021.03.01
[Java] Java란? Java의 특징  (0) 2021.02.16
[Java] 정규식 문법 정리(Regex)  (2) 2021.01.20
[Java] JVM, JDK, JRE의 차이  (0) 2021.01.01
[Java] Iterable과 Iterator  (0) 2020.12.13