Java에서 제공하는 탐욕적 수량자(Greedy Quantifiers)를 사용하면 특정 표현식이 여러 번 반복되는 패턴을 손쉽게 매칭할 수 있습니다. 반복 횟수를 지정하는 대표적인 문법은 다음과 같습니다.
Exp{n}— 표현식 exp가 정확히 n번 나타나야 합니다.Exp{n}— 표현식 exp가 최소 n번 이상 나타나야 합니다.Exp{n,m}— 표현식 exp가 최소 n번, 최대 m번 사이로 나타나야 합니다.
예제 1: 정확히 5글자인 단어 매칭하기
아래 예제는 \w{5} 패턴을 사용하여 입력 문자열 중 정확히 5개의 단어 문자(영문자, 숫자, 밑줄)로 구성된 부분이 있는지 확인합니다.
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexExample {
public static void main(String args[]) {
// 5글자 단어를 허용하는 정규식
String regex = "\\w{5}";
Scanner sc = new Scanner(System.in);
System.out.println("Enter 5 input strings: ");
String input[] = new String[5];
for (int i = 0; i < 5; i++) {
input[i] = sc.nextLine();
}
// Pattern 객체 생성
Pattern p = Pattern.compile(regex);
for (int i = 0; i < 5; i++) {
// Matcher 객체 생성
Matcher m = p.matcher(input[i]);
if (m.find()) {
System.out.println(input[i] + ": accepted");
} else {
System.out.println(input[i] + ": not accepted");
}
}
}
}실행 결과
Enter 5 input strings: rama raja raghu megha malya rama: not accepted raja: not accepted raghu: accepted megha: accepted malya: accepted
rama와 raja는 4글자라서 탈락하고, 5글자인 raghu, megha, malya만 통과한 것을 확인할 수 있습니다.
예제 2: 2~6자리 비단어 문자 매칭하기
이번에는 \W{2,6} 패턴을 사용해, 단어 문자가 아닌 문자(특수문자 등)가 2개 이상 6개 이하로 연속된 부분을 찾습니다.
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexExample {
public static void main(String args[]) {
// 길이가 2~6인 비단어(non-word) 문자열에 매칭되는 정규식
String regex = "\\W{2,6}";
Scanner sc = new Scanner(System.in);
System.out.println("Enter 5 input strings: ");
String input[] = new String[5];
for (int i = 0; i < 5; i++) {
input[i] = sc.nextLine();
}
// Pattern 객체 생성
Pattern p = Pattern.compile(regex);
for (int i = 0; i < 5; i++) {
// Matcher 객체 생성
Matcher m = p.matcher(input[i]);
if (m.find()) {
System.out.println(input[i] + " matched");
}
}
}
}실행 결과
Enter 5 input strings: hello how are you #$#% # #$@%%#&#& sample text #$#% matched #$@%%#&#& matched
일반 영어 문장이나 한 글자짜리 특수문자는 조건에 맞지 않아 제외되고, 연속된 특수문자로 이루어진 두 문자열만 매칭되었습니다.
예제 3: 학생 이름 유효성 검사하기
마지막 예제는 [a-zA-Z]{1,20} 패턴으로, 알파벳 대소문자가 1자 이상 20자 이하로만 구성된 이름인지 검사합니다. 여기서는 find() 대신 전체 문자열이 패턴과 완전히 일치해야 하는 matches() 메서드를 사용한다는 점에 주목하세요.
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexExample {
public static void main(String args[]) {
String regex = "[a-zA-Z]{1,20}";
Scanner sc = new Scanner(System.in);
System.out.println("Enter students name:");
String name = sc.nextLine();
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(name);
if (m.matches()) {
System.out.println("Name is appropriate");
} else {
System.out.println("Name is inappropriate");
}
}
}실행 결과
Enter students name: Mouktika Name is appropriate
정리
Java 정규식에서 반복 횟수를 제어하는 수량자는 세 가지 형태로 정리할 수 있습니다.
| 패턴 | 의미 |
|---|---|
X{n} | 정확히 n번 반복 |
X{n} | n번 이상 반복 |
X{n,m} | n번 이상 m번 이하 반복 |
또한 부분 일치를 찾을 때는 Matcher.find()를, 입력값 전체가 패턴을 만족하는지 검증할 때는 Matcher.matches()를 사용하는 것이 좋습니다. 이 두 메서드의 차이를 이해하면 이름 검증, 입력값 필터링 등 실무적인 유효성 검사 로직을 더욱 정확하게 작성할 수 있습니다.