자바 정규식에서 소유적 수량자(Possessive Quantifier)인 [X?+]는 X가 한 번 나타나거나 아예 나타나지 않는 경우와 일치합니다.
일반적인 탐욕적(Greedy) 수량자 X?나 게으른(Reluctant) 수량자 X??와 달리, 소유적 수량자 X?+는 매칭에 성공한 후 백트래킹(backtracking)을 통해 매칭을 결코 포기하지 않습니다. 이러한 특성 덕분에 복잡한 패턴에서 불필요한 역추적으로 인한 성능 저하를 방지할 수 있습니다.
예제 코드
package com.tutorialspoint;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PossesiveQuantifierDemo {
private static final String REGEX = "T?+";
private static final String INPUT = "abcdTatW";
public static void main(String[] args) {
// 패턴 생성
Pattern pattern = Pattern.compile(REGEX);
// 매처(Matcher) 객체 생성
Matcher matcher = pattern.matcher(INPUT);
while(matcher.find()) {
// 매칭된 문자열의 시작 인덱스 출력
System.out.println("Match String start(): " + matcher.start());
}
}
}실행 결과
Match String start(): 0 Match String start(): 1 Match String start(): 2 Match String start(): 3 Match String start(): 4 Match String start(): 5 Match String start(): 6 Match String start(): 7 Match String start(): 8
결과 분석
입력 문자열 "abcdTatW"에서 문자 T는 인덱스 4에 위치합니다. 패턴 T?+는 해당 위치에 T가 존재하면 이를 소비하여 매칭하고, T가 없으면 길이가 0인 빈 문자열과 일치합니다.
따라서 인덱스 0~3에서는 빈 매칭이 발생하고, 인덱스 4에서 실제 문자 T와 매칭됩니다. 이후 인덱스 5~7에서 다시 빈 매칭이 이루어지며, 마지막으로 문자열 끝 위치인 인덱스 8에서 한 번 더 빈 매칭이 발생하여 총 9개의 결과가 출력됩니다.
세 가지 수량자 비교
자바 정규식은 물음표(?) 수량자에 대해 세 가지 방식을 제공합니다.
- 탐욕적(Greedy):
X?— 최대한 매칭을 시도하되, 전체 매칭 실패 시 백트래킹으로 양보합니다. - 게으른(Reluctant):
X??— 최소한으로 매칭을 시도합니다. - 소유적(Possessive):
X?+— 매칭에 성공하면 백트래킹 없이 결과를 확정합니다.
단일 문자에 대한 ? 수량자에서는 세 방식의 차이가 크게 체감되지 않지만, 중첩된 수량자나 복잡한 패턴에서는 소유적 수량자가 치명적 백트래킹(catastrophic backtracking)을 방지하여 처리 속도를 크게 향상시킬 수 있습니다.