etc/Regex

Java Matcher 클래스 완벽 가이드 – 정규식 활용과 주요 메서드 정리

TechLogbook 2025. 2. 26. 10:19

Java의 Matcher 클래스는 Pattern 클래스와 함께 정규식을 활용한 문자열 처리를 수행하는 핵심 클래스입니다.
이번 포스트에서는 Matcher의 주요 메서드와 사용법을 예제와 함께 설명합니다.


1. Matcher 객체 생성 방법

Matcher 객체는 Pattern 객체를 이용해 생성됩니다.

import java.util.regex.*;

public class MatcherExample {
    public static void main(String[] args) {
        String text = "Hello, my email is example@email.com!";
        String regex = "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}";

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

        while (matcher.find()) {
            System.out.println("Found: " + matcher.group());
        }
    }
}

실행 결과:

Found: example@email.com

2. Matcher 주요 메서드 정리

메서드 설명
find() 문자열 내에서 패턴을 찾음
matches() 문자열 전체가 패턴과 일치하는지 확인
lookingAt() 문자열 시작 부분이 패턴과 일치하는지 확인
group() 매칭된 문자열 반환
start() / end() 매칭된 부분의 인덱스 반환
replaceAll() 모든 매칭된 부분을 변경
replaceFirst() 첫 번째 매칭된 부분을 변경
reset() Matcher를 초기 상태로 재설정하여 다시 검색 가능
wait() 현재 객체가 다른 스레드의 알림을 기다림 (멀티스레드 환경에서 사용)
notify() wait() 상태의 스레드를 깨움
hashCode() Matcher 객체의 해시코드를 반환
appendReplacement() 특정 문자열을 새로운 값으로 교체하며 StringBuffer에 추가
region() 검색할 문자열의 특정 부분을 지정
usePattern() 현재 Matcher에 새로운 Pattern을 설정
useAnchoringBounds() 정규식이 문자열의 경계를 고려할지 설정
useTransparentBounds() 정규식이 region()으로 지정한 범위를 넘어서 검사할지 설정

3. 추가 Matcher 메서드 상세 설명 및 예제

1) wait()notify()

wait()notify()Object 클래스에서 상속된 메서드로, Matcher 클래스에서도 사용할 수 있습니다.
주로 멀티스레딩 환경에서 특정 작업이 완료될 때까지 대기하거나 알림을 보낼 때 사용됩니다.

예제: wait()notify() 활용

public class MatcherThreadExample {
    private static final Object lock = new Object();

    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            synchronized (lock) {
                try {
                    System.out.println("Thread 1 waiting...");
                    lock.wait(); // Thread 1이 대기
                    System.out.println("Thread 1 resumed.");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            synchronized (lock) {
                System.out.println("Thread 2 notifying...");
                lock.notify(); // Thread 2가 Thread 1을 깨움
            }
        });

        thread1.start();
        try { Thread.sleep(1000); } catch (InterruptedException e) { }
        thread2.start();
    }
}

실행 결과:

Thread 1 waiting...
Thread 2 notifying...
Thread 1 resumed.

2) hashCode()

  • Matcher 객체의 고유한 해시코드를 반환합니다.
Matcher matcher = Pattern.compile("\\d+").matcher("12345");
System.out.println(matcher.hashCode());

출력 예시:

12345678  (객체마다 다름)

3) appendReplacement()

  • 특정 문자열을 매칭된 부분과 교체하면서 StringBuffer에 추가할 수 있습니다.
import java.util.regex.*;

public class AppendReplacementExample {
    public static void main(String[] args) {
        String text = "The price is $30 and the discount is $5";
        String regex = "\\$\\d+";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(text);
        StringBuffer sb = new StringBuffer();

        while (matcher.find()) {
            matcher.appendReplacement(sb, "[CURRENCY]");
        }
        matcher.appendTail(sb);
        System.out.println(sb.toString());
    }
}

출력:

The price is [CURRENCY] and the discount is [CURRENCY]

4) region(int start, int end)

  • Matcher의 검색 범위를 지정할 수 있습니다.
Matcher matcher = Pattern.compile("\\d+").matcher("ID: 12345, Code: 67890");
matcher.region(4, 10);

while (matcher.find()) {
    System.out.println("Match: " + matcher.group());
}

출력:

Match: 12345

5) usePattern(Pattern newPattern)

  • 기존 Matcher 객체에 새로운 정규식을 적용합니다.
Pattern p1 = Pattern.compile("\\d+");
Matcher matcher = p1.matcher("12345");
System.out.println(matcher.find()); // true

Pattern p2 = Pattern.compile("[a-zA-Z]+");
matcher.usePattern(p2);
System.out.println(matcher.find()); // false

6) useAnchoringBounds(boolean value)

  • true: region() 범위 내에서 ^$가 적용됨
  • false: region()을 넘어 전체 문자열을 기준으로 ^$를 적용함
Matcher matcher = Pattern.compile("^\\d+").matcher("12345, 67890");
matcher.region(7, 12).useAnchoringBounds(true);

System.out.println(matcher.find()); // false (부분 매칭이 아니라 전체 문자열 기준)
matcher.useAnchoringBounds(false);
System.out.println(matcher.find()); // true (부분 매칭 허용)

7) useTransparentBounds(boolean value)

  • true: region()을 넘어 전체 문자열을 탐색할 수 있음
  • false: region() 내에서만 탐색 가능
Matcher matcher = Pattern.compile("Code:\\s(\\d+)").matcher("ID: 12345, Code: 67890");
matcher.region(4, 20).useTransparentBounds(false);

System.out.println(matcher.find()); // false
matcher.useTransparentBounds(true);
System.out.println(matcher.find()); // true

4. 결론

Java의 Matcher 클래스는 문자열 검색, 변환 및 조작을 위한 다양한 기능을 제공합니다.

  • wait()notify()를 통해 멀티스레드 환경에서도 활용할 수 있습니다.
  • appendReplacement()를 활용해 문자열을 동적으로 변경할 수 있습니다.
  • region(), usePattern(), useAnchoringBounds(), useTransparentBounds()를 사용하여 세밀한 검색을 수행할 수 있습니다.

이제 Matcher의 다양한 기능을 직접 활용해보세요! 🚀

'etc > Regex' 카테고리의 다른 글

정규식 테스트를 위한 최고의 웹사이트 모음  (1) 2025.02.05
정규식  (1) 2025.01.22