Post

[JAVA]자바 정규표현식(Regex)

정규표현식

코딩테스트 문자열처리 문제를 풀 때, Stringchar[] 자료형으로 쪼개서 하나씩 처리를 해주는 경우가 많았는데 정규식을 이용한 라이브러리를 사용하면 함수하나로 간단하게 처리할 수 있다.

개발에서는 아이디나 비밀번호 조합을 잘 지켰는지 확인하는데 쓰인다. 맨날 비번만들때, 특수문자 섞으라는것을 체크하는 로직이 이 정규식을 활용한 것이다.

맨처음에는 정규식의 문법들을 설명해주는데, 활용방법을 바로 보고싶은분들은 Regex 지원하는 String 메소드 를 확인해주시면 된다.

Metacharacters

Regex 패턴에서 특별한 의미를 갖는 것

Regular ExpressionDescription
.어떤 문자 1개를 의미
^abcabc 로 시작
abc$abc 로 끝남
[abc]a, b, c 중 문자 1개
[abc][vz]a, b, c 중에 문자 1개와 v, z 중에 문자 1개의 조합
[^abc]a, b, c를 제외한 문자 1개, [] 에서는 ^ 은 NOT 을 의미한다.
[a-d1-3]a, b, c, d, 1, 2, 3 중에 문자 1개
\d0~9 사이의 숫자, [0-9]와 동일
\D숫자가 아닌 어떤 문자, [^0-9]와 동일
\swhitespace 1개, [\t\n\x0b\r\f]와 동일
\Swhitespace를 제외한 문자
\w문자, [a-zA-Z_0-9]와 동일
\W문자가 아닌것
\b경계구분, 다른 문자와 결합되지않은 독립된 문자 찾을때 사용

Java 에서는 \ 를 사용할때에는 \\ 로 사용해야 한다. 예를 들어 숫자인 문자를 필터링할려고 \d 를 사용하면 인식이 되지 않고, \\d 를 사용해야 한다.

그리고 ., ^, $ 등 특수한 문자를 필터링해야 될 때가있으면 앞에 \\ 를 붙여서 \\., \\^, \\$ 사용해서 필터링을 할 수 있다.

Quantifier

얼마나 반복시킬지 정의하는것

Regular ExpressionDescription
*0회 이상 반복
+1회 이상 반복
?0 또는 1회만
{X}X회 이상 반복
{X, Y}X~Y 사이의 수만큼 반복

Grouping

패턴에 그룹을 지정하는것, 그룹은 () 로 지정할 수 있다. 그리고 그룹을 표현할 때 $1 처럼 $ 다음에 번호를 붙여 그룹을 표현한다. 해당 표현으로 그룹을 호출하여 원하는 결과를 만들 수 있다.

1
2
3
4
5
6
7
String pattern = "(\\w)(\\s+)([\\w])";
pattern = pattern.replaceAll("Hello     World", "$1-$3");
// 패턴으로 찾은 문자가 o     W 이고
// $1 그룹으로 찾은 문자가 "o"
// $2 그룹으로 찾은 문자가 "     "
// $3 그룹으로 찾은 문자가 "W"
// o     W -> $1-$3 -> o-W 로 변환되면서 Hello-World 가 출력된다.

Regex 지원하는 String 메소드

String MethodDescription
String.matches(regex)String 이 regex 와 일치하면 true 반환
String.split(regex)regex와 일치하는 것을 기준으로 String을 분리하여 배열로 반환
String.replaceFirst(regex, replacement)regex와 가장 먼저 일치하는 것을 replacement로 변환
String.replaceAll(regex, replacement)regex와 일치하는 모든 것을 replacement로 변환

replaceAll 의 경우 특정 문자열을 원하는 문자열로 변경할때 자주 사용한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Metacharacters 활용 예제
String word = "what is wrong? what is time? whats mean?";
String test1 = word.replaceAll("\\bwhat\\b", "when"); //  when is wrong? when is time? whats mean?
String test2 = word.replaceAll("[wrong]", "1"); // 1hat is 11111? 1hat is time? 1hats mea1?
String test3 = word.replaceAll("wrong", "1"); // what is 1? what is time? whats mean?
String test4 = word.replaceAll("^what", "1"); // 1 is wrong? what is time? whats mean?
String test5 = word.replaceAll("\\?$", "1"); // what is wrong? what is time? whats mean1
String test6 = word.replaceAll("[ges][\\?\\s]", "1"); // what i1wron1 what i1tim1 what1mean?

// Quantifier 활용 예제
String word2 = "aaaabbbccccccdee";
String test7 = word2.replaceAll("a+", "1"); // 1bbbccccccdee
String test8 = word2.replaceAll("[abcde]+", "1"); // 1
String test9 = word2.replaceAll("a+b+", "1"); // 1ccccccdee
String test10 = word2.replaceAll("a?", "1"); // 11111b1b1b1c1c1c1c1c1c1d1e1e1 ( a가 존재하면 a -> 1, 존재안하면 "" -> 1이기 때문)
String test11 = word2.replaceAll("[c]{4,5}", "1"); // aaaabbb1cdee
String test12 = word2.replaceAll("[abcde]{10,11}", "1"); // 1ccdee (aaaabbbcccc -> 1)
String test13 = word2.replaceAll("a{4}|b{4}|c{4}|d{4}|e{4}", "1"); // 1bbb1ccdee

Pattern Matcher

정규식을 컴파일 하여 Pattern 객체에 저장해 둘 수 있다. Matcher 에는 어떤 문자열에 적용할지 전달해 주어야 한다.

1
2
Pattern pattern = Pattern.compile("(\\w)(\\s+)([\\w])");
Matcher matcher = pattern.matcher("Hello     World");

Matcher 에 컴파일방식과 문자열을 지정해주었다면, Matcher 의 다양한 기능을 사용할 수 있다.

Regular ExpressionDescription
matches()대상 문자열과 패턴이 일치하는 경우 true 반환
find()대상 문자열과 패턴이 일치하는 경우 true 반환 하고 그 위치로 이동
find(int start)start 지점부터 매칭 체크
start()매칭되는 문자열의 시작 인덱스를 반환
end()매칭되는 문자열의 마지막 다음 인덱스를 반환
group()매칭된 문자열 반환
group(int group)매칭된 부분 중 group번째 그루핑 매칭 문자열 반환
groupCount()패턴에 그룹핑한 전체 갯수를 반환

find() 함수의 경우 Matcher 객체 내부에서 위치로 이동하는것으로 group(), start(), end() 함수랑 같이 사용 한다.

1
2
3
4
5
6
7
8
Pattern pattern = Pattern.compile("(cat)(1?)");
Matcher matcher = pattern.matcher("cat12 cat11 cat14 cattie15 cat16");
System.out.println("group(): " + matcher.groupCount()); // $1 이 cat, $2 가 1? 로 총 그룹핑 개수는 2개 입니다.
while(matcher.find()) {
    System.out.println("group(): " + matcher.group(1));
    // cat cat cat cat cat
    // matcher.group(1) 은 그룹핑 첫번째 $1 인 cat 패턴으로 찾은 값만 반환됩니다.
}

Reference

https://codechacha.com/ko/java-regex/
https://hbase.tistory.com/160
https://enterkey.tistory.com/353

This post is licensed under CC BY 4.0 by the author.