Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

자바(Java) 정규식 비탐욕(Reluctant) 수량자 완벽 정리


정규식에서 수량자(quantifier)는 패턴이 반복되는 횟수를 지정하는 특수 문자입니다. 수량자는 크게 탐욕적(Greedy) 방식과 비탐욕적(Reluctant, Non-greedy) 방식으로 나뉩니다.

탐욕적 수량자와 비탐욕적 수량자의 차이

탐욕적(Greedy) 수량자는 기본값으로 설정되어 있으며, 입력 문자열에서 가능한 한 가장 많은 부분(최대 길이 일치)을 찾으려고 시도합니다. 만약 매칭에 실패하면 마지막 문자 하나를 제외하고 다시 매칭을 시도하는 방식으로 동작합니다.

반면 비탐욕적(Reluctant) 수량자는 정반대로 가능한 한 가장 적은 부분(최소 길이 일치)만 찾습니다. 처음에는 첫 번째 문자 하나만으로 매칭을 시도하고, 실패할 경우 입력 문자열에서 문자를 하나씩 추가해 가며 매칭을 반복합니다.

비탐욕적 수량자 만드는 방법

탐욕적 수량자 뒤에 물음표(?)를 붙이면 해당 수량자는 비탐욕적(reluctant) 수량자로 변경됩니다. 주요 비탐욕적 수량자 목록은 다음과 같습니다.

수량자설명
re*?0번 이상 일치
re??0번 또는 1번 일치
re+?1번 이상 일치
re{n}?정확히 n번 일치
re{n}?최소 n번 이상 일치
re{n, m}?최소 n번, 최대 m번 일치

예제 코드

아래 예제는 비탐욕적 수량자 [0-9]+?를 사용하여 숫자를 한 글자씩 개별적으로 매칭하는 자바 프로그램입니다.

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter input text: ");
        String input = sc.nextLine();
        String regex = "[0-9]+?";
        // 패턴 객체 생성
        Pattern pattern = Pattern.compile(regex);
        // 컴파일된 패턴을 문자열과 매칭
        Matcher matcher = pattern.matcher(input);
        while (matcher.find()) {
            System.out.print("Pattern found from " + matcher.start()+ " to " + (matcher.end()-1)+"::");
            System.out.print(matcher.group());
            System.out.println();
        }
    }
}

실행 결과

입력으로 12345678을 넣으면, 비탐욕적 수량자는 각 숫자를 하나씩만 매칭하므로 아래와 같이 한 자리씩 개별 결과가 출력됩니다.

Enter input text:
12345678
Pattern found from 0 to 0::1
Pattern found from 1 to 1::2
Pattern found from 2 to 2::3
Pattern found from 3 to 3::4
Pattern found from 4 to 4::5
Pattern found from 5 to 5::6
Pattern found from 6 to 6::7
Pattern found from 7 to 7::8

만약 같은 패턴을 탐욕적 수량자인 [0-9]+로 실행했다면, 전체 문자열 12345678이 하나의 매칭 결과로 출력되었을 것입니다. 이처럼 비탐욕적 수량자는 최소 단위로 잘라서 매칭하고 싶을 때 유용하게 활용됩니다.