우아한테크코스[프리코스]

[1주 차] 정규표현식과 메타문자, 그리고 java.util.regex 패키지

문상휘파람 2024. 10. 19. 01:11

1주 차 미션을 완성하였습니다!

 

완성은 하였는데....사실 고치고 싶은 부분이 많아요.

검증 처리 로직도 따로 빼고 싶습니다.


그런데 !!! 이번에 치명적인 문제를 발견하였습니다!

-> 정규표현식에서 메타문자를 읽어들이지 못하는 코드를 짰습니다...!

 

*StringParser

public String extractDelimiter() {
    if (!inputStrings.startsWith(FIRST_CUSTOM_STRING)) {
        return STANDARD_DELIMITER;
    }
    validateCustomStrings(inputStrings);
    return inputStrings.substring(SECOND_NUMBER, inputStrings.indexOf(CUSTOM_NUMBER_PART_DELIMITER));
}

구분자를 추출하는 메서드인데요, 메타문자를 읽어들이지 못하는 상태입니다..!

결과

실제로 메타 문자를 입력하게 되면, PatternSyntaxException 예외처리가 발생합니다.....


그래서 정규표현식에 대해 공부좀 하면서, java에 정규 표현식을 처리할 수 있는 패키지가 있더라고요??

바로 java.util.regex 패키지 입니다.

 

*StringParser

public String extractDelimiter() {
    if (!inputStrings.startsWith(FIRST_CUSTOM_STRING)) {
        return STANDARD_DELIMITER;
    }
    validateCustomStrings(inputStrings);
    return Pattern.quote(inputStrings.substring(SECOND_NUMBER, inputStrings.indexOf(CUSTOM_NUMBER_PART_DELIMITER)));
}

해당 패키지를 통해, Pattern.quote 메서드를 사용하면서 정규식 입력에 대한 오류를 고칠 수 있었습니다!

결과

요런 식으로 결과가 잘 도출됩니다 ㅎㅎ..


이번에 오류를 고치면서 정규표현식과 메타문자, 그리고 java.util.regex 패키지를 공부하였는데요! 해당 내용을 공유합니다!

 

 

정규 표현식과 메타문자

정규 표현식이란?

  • 정규 표현식(Regular Expression, RegEx) 은 특정한 패턴을 가진 문자열을 찾고, 처리하는 데 사용되는 표현식입니다.

정규 표현식의 주요 기능

  • 검색: 텍스트에서 특정 패턴에 맞는 문자열을 찾습니다.
  • 검증: 입력 문자열이 특정 형식(예: 이메일 주소, 전화번호 등)에 맞는지 검증합니다.
  • 치환: 특정 패턴에 맞는 부분 문자열을 다른 문자열로 변경합니다.
  • 분리: 문자열을 특정 패턴을 기준으로 나누어 배열로 변환합니다.

정규 표현식 예시

  1. 숫자로만 이루어진 문자열:
    ^\d+$ → 숫자로만 이루어진 문자열을 찾습니다.
  2. 이메일 형식:
    ^\w+@\w+\.\w+$ → 이메일 주소 형식을 확인하는 정규 표현식입니다.
  3. 특정 단어로 시작하는 문자열:
    ^Hello → "Hello"로 시작하는 문자열을 찾습니다.

각 문자 요소가 어떤 의미를 나타내는지는 아래에서 설명하겠습니다


메타문자란?

  • 메타 문자(Meta Characters) 는 정규 표현식에서 특수한 의미를 가지는 문자들입니다. 메타 문자는 특정 패턴을 정의하거나 제어하는 역할을 하며, 일반 문자와 다르게 해석됩니다.

자주 사용되는 메타문자 예시

  1. . (마침표):
    임의의 한 문자를 나타냅니다. 단, 줄바꿈 문자는 제외됩니다.
    ex) a.b → a와 b 사이에 임의의 문자가 있는 패턴 (a1b, acb 등).
  2. ^:
    문자열의 시작을 나타냅니다.
    ex) ^Hello → "Hello"로 시작하는 문자열.
  3. $:
    문자열의 끝을 나타냅니다.
    ex) end$ → "end"로 끝나는 문자열.
  4. *:
    앞의 패턴이 0번 이상 반복됨을 의미합니다.
    ex) a* → a가 0번 이상 반복되는 패턴 ("a", "aaa", "").
  5. +:
    앞의 패턴이 1번 이상 반복됨을 의미합니다.
    ex) a+ → a가 1번 이상 반복되는 패턴 ("a", "aaa").

메타문자 이스케이프 처리 하는 방법

  • 메타 문자는 정규 표현식에서 특별한 의미를 가지므로, 이를 일반 문자로 사용하려면 이스케이프 처리가 필요합니다. 이스케이프 처리는 메타 문자 앞에 \ 를 붙여서 해당 문자를 나타낼 수 있습니다.
  • ex) . → \. (문자 . 자체를 찾습니다), ? → \? (문자 ? 자체를 찾습니다)

정규 표현식 해석하는 방법

^\d+$

  • ^: 문자열의 시작을 나타냅니다.
  • \d: 숫자를 나타냅니다.
  • +: 숫자가 1번 이상 반복됨을 의미합니다.
  • $: 문자열의 끝을 나타냅니다.
  • 최종 : 숫자로만 이루어진 문자열을 찾아내는 정규식으로 해석할 수 있습니다!

정규 표현식은 너무나도 많고, 무한정으로 커스텀 가능합니다. 여기 사이트를 참고하셔서 더 많은 정규식에 대해 학습하실 수 있습니다!


자바에서 정규식을 처리하는 패키지 - java.util.regex 패키지

  • java.util.regex 패키지는 Java에서 정규 표현식(Regular Expressions)을 사용하여 문자열을 처리하는 기능을 제공하는 패키지입니다. 위에서 설명한 텍스트 매칭, 검색,
    치환 등의 작업을 수행할 수 있도록 도와줍니다. 주로 패턴 매칭정규식 검색과 관련된 작업에 사용됩니다.

[주요 클래스]

1. Pattern 클래스

  • 정규 표현식 패턴을 나타내는 클래스입니다.
  • 컴파일한 결과를 저장하고, 이를 기반으로 문자열을 매칭할 수 있습니다.
  • 주요 메서드:
    • compile(String regex): 주어진 정규 표현식을 컴파일하여 Pattern 객체를 생성합니다.
    • matcher(CharSequence input): 입력 문자열에 대해 이 패턴을 사용하여 매칭을 수행할 Matcher 객체를 반환합니다.
    • split(CharSequence input): 주어진 패턴을 기준으로 입력 문자열을 나눕니다.
    • quote(String s): 정규식 메타 문자가 포함된 문자열을 이스케이프 처리하여 안전하게 사용할 수 있도록 변환합니다.

2. Matcher 클래스

  • 입력 문자열과 패턴을 매칭하는 클래스입니다.
  • Pattern 객체로부터 생성되며, 패턴이 입력 문자열과 일치하는지를 확인하는 데 사용됩니다.
  • 주요 메서드:
    • find(): 패턴에 맞는 다음 부분 문자열을 찾습니다.
    • matches(): 입력 문자열이 패턴과 완전히 일치하는지 확인합니다.
    • group(): 매칭된 부분 문자열을 반환합니다.
    • replaceAll(String replacement): 패턴에 맞는 모든 부분을 대체 문자열로 치환합니다.

3. PatternSyntaxException 클래스

  • 잘못된 정규 표현식을 사용했을 때 발생하는 예외 클래스입니다.
  • 정규식을 컴파일할 때 잘못된 패턴이 있으면 이 예외가 발생합니다.
  • 주요 메서드:
    • getDescription(): 예외의 상세 설명을 반환합니다.
    • getIndex(): 오류가 발생한 정규식 내 위치를 반환합니다.
    • getPattern(): 문제를 일으킨 정규 표현식을 반환합니다.

예시 코드

  • StringParser
public String extractDelimiter() {
        if (!inputStrings.startsWith(FIRST_CUSTOM_STRING)) {
            return STANDARD_DELIMITER;
        }
        validateCustomStrings(inputStrings);
        return Pattern.quote(inputStrings.substring(SECOND_NUMBER, inputStrings.indexOf(CUSTOM_NUMBER_PART_DELIMITER)));
    }
  • quote 메서드를 사용함. -> //?\n1?2?3 과 같은 입력이 들어오면 ?를 문자로 읽어들여 추출할 수 있습니다. 위에서 설명드린 내용입니다..!

결론

  • java.util.regex 패키지는 정규 표현식을 사용하여 문자열 매칭, 검색, 치환 등의 작업을 수행하는 기능을 제공합니다.
  • Pattern 클래스는 정규식을 컴파일하고, Matcher 클래스는 입력 문자열과 패턴을 매칭합니다.
  • PatternSyntaxException 은 잘못된 정규 표현식이 사용될 때 발생하는 예외입니다.

참고문서 https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/regex/package-summary.html