Java 정규식

2024. 11. 19. 18:16Java/Java

정규식의 개념

- 정규식(Regular Expression, regex)은 문자열에서 특정 패턴을 정의하고, 이를 검색하거나 변환하는데 사용하는 강력한 도구입니다.

- 문자열을 효율적으로 처리하는 데 유용하며, 패턴을 기반으로 문자열을 검증하거나 변형하는 작업을 할 수 있습니다.

- 정규식은 언어 독립적이며, 대부분의 프로그래밍 언어에서 공통적으로 지원합니다.

- 정규식의 문법은 프로그래밍 언어에 따라 조금씩 다를 수 있지만, 대부분의 언어는 비슷한 표준을 따르고 있습니다. 

 


자바에서의 정규식 사용법

자바에서 정규식은 java.util.regex 패키지를 통해 사용됩니다.

주요 클래스는 PatternMatcher입니다.

  • Pattern 클래스는 정규식을 컴파일하고
  • Matcher 클래스는 문자열에 정규식을 적용하여 매칭을 수행합니다.

기본 사용법

  1. 정규식 패턴 작성
  2. 정규식 패턴 컴파일 (Pattern.compile())
  3. 매칭 (Pattern.matcher())
  4. 매칭 확인 및 결과 추출 (Matcher.find(), Matcher.group() 등)
import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        // 1. 정규식 패턴 작성
        String regex = "\\d{3}"; // 숫자 3자리 패턴

        // 2. 정규식 패턴 컴파일
        Pattern pattern = Pattern.compile(regex);

        // 3. 매칭: 패턴과 문자열을 연결
        String text = "123 abc 456";
        Matcher matcher = pattern.matcher(text);

        // 4. 매칭 확인 및 결과 추출
        if (matcher.find()) {
            System.out.println("매칭됨!"); // 출력
            System.out.println("매칭된 부분: " + matcher.group()); // "123" 출력
        } else {
            System.out.println("매칭되지 않음.");
        }
    }
}

 

Matcher 객체의 주요 메서드 

 

1. matches()

  • 입력 문자열 전체가 패턴과 완전히 일치하면 true 반환.
  • 주로 문자열 검증(예: 이메일 주소 확인)에 사용.
import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        String input = "12345";
        String regex = "^[0-9]+$"; // 숫자로만 이루어진 문자열인지 확인

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

        if (matcher.matches()) {
            System.out.println("문자열이 숫자만 포함하고 있어요!");
        } else {
            System.out.println("문자열에 숫자가 아닌 문자가 포함되어 있어요!");
        }
    }
}

 

 

2.  find()

  • 입력 문자열에서 정규식 패턴에 일치하는 부분이 있으면 true 반환.
  • 여러 개의 매칭 결과를 순차적으로 찾을 때 사용.

3. group()

  • 매칭된 결과를 반환.
  • 캡처 그룹(괄호로 감싼 부분)을 활용할 때도 유용.
import java.util.regex.*;

public class RegexExample {
    public static void main(String[] args) {
        String input = "오늘은 2024년 11월 19일입니다.";
        String regex = "\\d+"; // 숫자 패턴 (\\d는 숫자, +는 한 번 이상)

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

        while (matcher.find()) {
            System.out.println("찾은 숫자: " + matcher.group());
        }
    }
}

 

4. replaceAll() -> String 클래스의 메서드

  • 패턴에 매칭된 부분을 특정 문자열로 변환.
  • replaceAll()은 String 클래스의 메서드로, 정규식 패턴을 사용해 문자열을 처리.
  • Matcher 객체와 Pattern은 주로 매칭이나 검색을 위해 사용되지만, replaceAll()은 변경 작업에 활용되는 메서드.
public class ReplaceAllExample {
    public static void main(String[] args) {
        String text = "123 abc 456";
        // 숫자 3자리를 "X"로 교체
        String result = text.replaceAll("\\d{3}", "X");
        System.out.println(result);  // "X abc X" 출력
    }
}
 

정규식 문법

1. 괄호를 사용하는 경우

괄호는 특정 기능을 수행할 때 사용됩니다.

1-1. 대괄호 [ ] : 문자 집합

특정 문자들 중 하나를 매칭하고 싶을 때 사용합니다.

  • [abc]: a, b, c 중 하나에 매칭.
  • [a-z]: 소문자 알파벳 a부터 z 중 하나에 매칭.
  • [0-9]: 숫자 0부터 9 중 하나에 매칭.
  • [^abc]: a, b, c를 제외한 문자에 매칭 (대괄호 속 ^는 부정을 의미).
  • [a-zA-Z]: 대소문자 알파벳 전부에 매칭.
String regex = "[a-z]";
String input = "b";
System.out.println(Pattern.matches(regex, input)); // true

 

1-2. 중괄호 { } : 반복 지정

문자의 반복 횟수를 지정합니다.

  • a{2}: a가 정확히 2번 반복.
  • a{2,}: a가 2번 이상 반복.
  • a{2,4}: a가 2번 이상 4번 이하 반복.
String regex = "a{2,4}"; // 'a'가 2~4번 반복
String input = "aaa";
System.out.println(Pattern.matches(regex, input)); // true

 

1-3. 소괄호 ( ) : 그룹화 및 캡처

그룹화

  • (abc): abc라는 특정 문자열과 매칭.
  • (a|b): a 또는 b와 매칭 (OR 조건).

캡처

캡처된 그룹은 나중에 참조할 수 있습니다.

  • (\\d{3})-(\\d{4}): 전화번호 형식에서 123-4567에서 123과 4567 각각을 캡처.
import java.util.regex.*;

String regex = "(\\d{3})-(\\d{4})"; // 세 자리 숫자, 하이픈, 네 자리 숫자
String input = "123-4567";

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

if (matcher.matches()) {
    System.out.println("전체 매칭: " + matcher.group(0)); // 전체 매칭된 문자열
    System.out.println("첫 번째 그룹: " + matcher.group(1)); // 123
    System.out.println("두 번째 그룹: " + matcher.group(2)); // 4567
}

 

2. 메타문자를 사용하는 경우 (괄호X)

메타문자는 정규식에서 특정한 의미를 가진 문자입니다.

2-1. 위치 지정 (앵커)

앵커는 텍스트에서 특정 위치를 지정하는 역할을 합니다.

  • ^: 문자열의 시작을 나타냅니다.
    • 예: ^Hello는 "Hello"로 시작하는 문자열과 매칭.
  • $: 문자열의 끝을 나타냅니다.
    • 예: world$는 "world"로 끝나는 문자열과 매칭.
String regex = "^hello$";
String input = "hello";
System.out.println(Pattern.matches(regex, input)); // true

 

2-2. 임의의 문자

  • . : 줄바꿈을 제외한 모든 문자 하나와 매칭.
    • 예: a.b → acb, a1b와 매칭.
String regex = "a.b";
String input = "acb";
System.out.println(Pattern.matches(regex, input)); // true

 

2-3. 반복 연산자

  • *: 0번 이상 반복.
    • 예: a* → 빈 문자열, a, aaa와 매칭.
  • +: 1번 이상 반복.
    • 예: a+ → a, aaa와 매칭.
  • ?: 0번 또는 1번 매칭.
    • 예: a? → 빈 문자열, a와 매칭.
String regex = "a*"; // 숫자 3자리 패턴
Pattern pattern = Pattern.compile(regex);

System.out.println(pattern.matcher("a").matches()); //true
System.out.println(pattern.matcher("a").find()); //true
System.out.println(pattern.matcher("aaab").matches()); //false
System.out.println(pattern.matcher("aaab").find()); //true

 

2-4. 문자 클래스 단축형

자주 쓰이는 문자 집합은 단축형으로 제공됩니다.

단축형 의미 동등한 표현
\d 숫자 (0-9) [0-9]
\D 숫자가 아닌 문자 [^0-9]
\w 단어 문자 (알파벳, 숫자, _) [a-zA-Z0-9_]
\W 단어 문자가 아닌 문자 [^a-zA-Z0-9_]
\s 공백 문자 (스페이스, 탭 등) [ \t\n\x0B\f\r]
\S 공백이 아닌 문자 [^ \t\n\x0B\f\r]
String regex = "\\d+";
String input = "12345";
System.out.println(Pattern.matches(regex, input)); // true

 

3. Lookahead/Lookbehind (심화)

조건을 만족하지만 매칭에 포함되지 않는 패턴을 작성할 때 사용합니다.

1) Lookahead:

  • (?=...): 뒤에 특정 패턴이 있는 경우 매칭.
  • (?!...): 뒤에 특정 패턴이 없는 경우 매칭.

2) Lookbehind:

  • (?<=...): 앞에 특정 패턴이 있는 경우 매칭.
  • (?<!...): 앞에 특정 패턴이 없는 경우 매칭.

예시 패턴 작성법

이메일 주소 검증

^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$
  • ^로 시작하고, $로 끝나는 문자열로 이메일 주소를 검증.
  • 알파벳, 숫자, 특수 기호를 포함하는 로컬 부분과, @ 뒤에 도메인을 검증.

전화번호 패턴 (예: 010-1234-5678)

^010-\d{4}-\d{4}$
  • 010-으로 시작하고, 숫자 4자리 + 하이픈 + 숫자 4자리로 이루어진 패턴.

 

자바에서 주의할 점

  • 자바에서는 백슬래시(\)를 이스케이프 문자로 사용하기 때문에 정규식을 쓸 때는 백슬래시 두 개 (\\)로 작성해야 함.