[JAVA]자바 정규표현식(Regex)
정규표현식
코딩테스트 문자열처리 문제를 풀 때, String
을 char[]
자료형으로 쪼개서 하나씩 처리를 해주는 경우가 많았는데 정규식을 이용한 라이브러리를 사용하면 함수하나로 간단하게 처리할 수 있다.
개발에서는 아이디나 비밀번호 조합을 잘 지켰는지 확인하는데 쓰인다. 맨날 비번만들때, 특수문자 섞으라는것을 체크하는 로직이 이 정규식을 활용한 것이다.
맨처음에는 정규식의 문법들을 설명해주는데, 활용방법을 바로 보고싶은분들은 Regex 지원하는 String 메소드 를 확인해주시면 된다.
Metacharacters
Regex 패턴에서 특별한 의미를 갖는 것
Regular Expression | Description |
---|---|
. | 어떤 문자 1개를 의미 |
^abc | abc 로 시작 |
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개 |
\d | 0~9 사이의 숫자, [0-9]와 동일 |
\D | 숫자가 아닌 어떤 문자, [^0-9]와 동일 |
\s | whitespace 1개, [\t\n\x0b\r\f]와 동일 |
\S | whitespace를 제외한 문자 |
\w | 문자, [a-zA-Z_0-9]와 동일 |
\W | 문자가 아닌것 |
\b | 경계구분, 다른 문자와 결합되지않은 독립된 문자 찾을때 사용 |
Java 에서는 \
를 사용할때에는 \\
로 사용해야 한다. 예를 들어 숫자인 문자를 필터링할려고 \d
를 사용하면 인식이 되지 않고, \\d
를 사용해야 한다.
그리고 .
, ^
, $
등 특수한 문자를 필터링해야 될 때가있으면 앞에 \\
를 붙여서 \\.
, \\^
, \\$
사용해서 필터링을 할 수 있다.
Quantifier
얼마나 반복시킬지 정의하는것
Regular Expression | Description |
---|---|
* | 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 Method | Description |
---|---|
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 Expression | Description |
---|---|
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