29. 정규식

Isaiah IM·2023년 9월 19일
0

java basic

목록 보기
31/38
post-thumbnail

1. 정규식(regex)

1.1 정규식이란?

정규식이란 텍스트에서 원하는 조건(패턴)과 일치하는 문자열을 찾아내기 위해 사용하는 기호이다.

일반적으로 우리가 웹 페이지에서 회원가입을 하는 상황을 보자.
회원가입시 비밀번호의 경우 보통은 9~16글자와 특수문자가 포함된 문자만이 비밀번호로 사용할 수 있는 경우를 자주 봤을 것이다.
만약 우리가 회원가입 로직을 설계하는 경우에는 사용자가 입력한 비밀번호를 문자열로 받아서 글자 수를 확인하고, 특수문자 포함 여부를 확인해야 할 것이다.
이러한 경우 정규식을 사용하면 쉽게 글자 수 확인과 특수문자 포함 여부를 알 수 있다.

9~16글자특수문자 포함이라는 규칙을 패턴이라고 한다.
정규식은 문자열 가운데에서 패턴들을 찾아내는데에 유용하게 사용된다.

1.2 정규식 패턴

정규식의 패턴은 문자 기호를 이용하며, 난해한 편이다.

그렇다. 이런것이 정규식 패턴이다...


정규식이 난해하다 보니 작성하면서 자연스럽게 크고 아름다운 법-규 가 발동되기도 한다.

모든 정규식을 외우기 보다는 때에 따라서 필요한 정규식 패턴을 chatGPT에 물어봐서 사용하는 것을 권장한다..

각설하고, 기본적인 정규식 패턴은 다음 표와 같다.

이를 이용해 휴대폰 번호를 검증하는 정규식은 다음과 같다.
(010)-\\d{4}-\\d{4}
이를 해석하면 다음과 같다.
(010)- 부분은 010으로 시작하고, - 기호가 있는 경우를 의미한다.

다음으로 \\d{4}-\d{4}-와 같은 것으로 정확히 4개의 숫자 이후에 -기호가 있는 경우를 의미한다.
즉, 여기까지 정규식을 적용하면 010-0000-부터 010-9999-까지 일치하도록 설계가 된다. 다시 말하면 020-0000-이나 010-00a0-는 정규식 조건에 일치하지 않는다고 반환이 된다.

마지막으로 \\d{4}\d{4}와 같은 것으로 정확히 4개의 숫자가 있는 경우를 의미한다.
여기까지 정규식을 적용하면 010-0000-0000부터 010-9999-9999까지 정규식 조건에 일치하도록 반환하면서 전화번호 정규식이 된다.

다음으로 주민등록 번호를 검증하는 정규식을 chatGPT한테 물어봐서 복붙 작성하면 다음과 같다.

(\d{2})(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])-[1-4]\d{6}
해석은 다음과 같다.
(\d{2}): 2자리 숫자
(0[1-9]|1[0-2]): 01~09 혹은 10~12
(0[1-9]|[12][0-9]|3[01]): 01~09 혹은 앞 자리가 1 아니면 2이면서 0~9 (10~29까지) 혹은 30 혹은 31. 이렇게 하면 (01~31까지가 된다)
-[1-4]\d{6}: - 붙이고, 1~4(00년생 이후에 태어난 응애들은 주민번호 뒷자리가 3, 4로 시작한다.) 그리고 숫자 6자리

이와 같이 정규식을 작성할 수 있다.

1.3 정규식의 사용

정규식은 String클래스 내에 있는 정규식 문법을 사용하는 방법과 regex패키지의 Pattern클래스와 Matcher클래스를 이용해 정규식을 사용할 수 있다.

String 클래스

String 클래스에서는 matches(String regex)메소드와 replaceAll(String regex, String replacement)메소드, split(String regex)메소드를 이용해 정규식을 사용할 수 있다.

boolean matches(String regex)메소드는 인자로 주어진 정규식이 일치하는 값이 있는지 확인해 boolean자료형으로 반환한다.

public class Main {
    public static void main(String[] args){
       String str = "12345";

       System.out.println(str.matches("[0-9]+"));// 문자열이 숫자로 이루어졌는가?
    }
}

output

true

String replaceAll(String regex, String replacement)메소드는 문자열내에 있는 정규식 regex와 매치되는 모든 문자열을 replacement 문자열로 바꾼 문자열을 반환하는 메소드이다.

public class Main {
    public static void main(String[] args){
       String ID = "980214-1234567";

       System.out.println(ID.replaceAll("-[0-9]+", "xxxxxxx"));// 주민번호 뒷자리 마스킹
    }
}

output

980214xxxxxxx

String[] split(String regex)메소드는 정규식과 매치되는 문자열을 구분자로 분할하는 메소드이다.

public class Main {
    public static void main(String[] args){
       String ID = "980214-1234567";

       String strs[] = ID.split("-");

       for(String str: strs){// 주민번호 앞/뒤자리 분리
           System.out.println(str);
       }
    }
}

output

980214
1234567

regex 패키지

자바에서는 정규 표현식을 전문적으로 다루는 클래스들을 모아서 java.util.regex 패키지를 통해 제공해준다. 패키지 안의 클래스에서는 주로 Pattern클래스와 Matcher클래스를 주로 사용된다.

Pattern클래스는 문자열을 정규식 패턴 객체로 반환한다. 이때, 올바른 정규식을 사용하지 않으면 예외가 발생할 수 있으므로 올바른 정규식을 작성해야 한다.
또한, Pattern클래스는 compile()메소드를 이용해 객체를 생성 및 호출할 수 있으며, 이는 Matcher클래스에서 사용된다.

Matcher 클래스는 대상 문자열의 패턴을 해석하고 주어진 패턴과 일치하는지 판별하고 반환된 결과값들을 갖고 있다. Matcher 클래스 역시 Pattern 클래스와 마찬가지로 공개된 생성자가 없다. Matcher객체는 Pattern 객체의 matcher() 메소드를 호출해서 얻는다.

public class Main {
    public static void main(String[] args){
       String ID = "980214-1234567";

       Pattern pattern = Pattern.compile("(\\d{6})-(\\d{7})");
       Matcher m = pattern.matcher(ID);

       System.out.println(m.find());
       System.out.println("주민번호 앞자리: "+m.group(1));
       System.out.println("주민번호 뒷자리: "+m.group(2));
    }
}

output

true
980214
1234567
profile
나는 생각한다. 고로 나는 코딩한다.

0개의 댓글