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

Java 정규식(RegEx)으로 표현식을 n번 일치시키는 방법

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

ramaraja는 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()를 사용하는 것이 좋습니다. 이 두 메서드의 차이를 이해하면 이름 검증, 입력값 필터링 등 실무적인 유효성 검사 로직을 더욱 정확하게 작성할 수 있습니다.