정규표현식이란?
정규표현식이란 문자열 데이터 중에서 원하는 조건과 일치하는 문자열을 찾기 위한것으로 미리 정의된 기호와 문자를 이용해 작성한 문자열을 말합니다.
전화번호 (010-1234-5678), 주민번호 (990101-1234567), 이메일(example@gmail.com) 과 같이 형식이 정해져있고 그 값을 검증할때 정규표현식을 사용하면 쉽게 구현할 수 있습니다.
정규표현식을 사용하면 데이터의 형식을 확인할 수 있는 장점이 있지만 식이 복잡하고 가독성이 떨어진다는 단점이 있습니다.
정규표현식
기호 | 설명 | 예제 |
. | 임의의 문자 1개를 의미합니다 | |
[ ] | 괄호안의 문자가 있는지 확인합니다. | [12ab] : 1,2,a,b 중 한 문자 |
- | 문자의 사이를 의미합니다. | [0-9] : 0 ~ 9 중 한 문자 [a-z] : a ~ z 중 한 문자 [A-Z] : A ~ Z 중 한 문자 [가-힣] : 가 ~ 힣 중 한 문자 [0-9a-z-A-Z가-힣] : 전체 문자 중 한 문자 |
^ | 문자의 시작을 의미합니다. | ^a : a로 시작하는 문자 ^[ab] : a,b 중 한 문자로 시작하는 문자 |
$ | 문자의 마지막을 의미합니다. 문자 뒤에 작성합니다. | a$ : a로 끝나는 문자 [a-z]$ : a ~ z 문자로 끝나는 문자 |
[^ ] | 괄호안의 문자를 제외합니다. | [^a-z] : a ~ z 까지의 문자를 제외한 모든 문자 [^123] : 1,2,3 문자를 제외한 모든 문자 |
| | 또는 | [a|b] : a 또는 b (abc|bcd) : abc 또는 bcd |
( ) | 그룹을 뜻합니다. | 01(0|1) : 01 뒤에 0 또는 1인 문자 |
{ } | 개수를 의미합니다. | a{3} : a가 3개인 문자 (aaa) 0{2}1 : 0이 2개이고 1이 온다 (001) |
기호 | 설명 | 예제 |
{n} | 앞의 표현식이 n개 있다. | a{3} : a가 3개인 문자 (aaa) [0-9]{3} : 숫자가 3개인 문자 (123, 531, 467, ... ) |
{n, m} | 앞의 표현식이 n개 이상 m개 이하가 있다. | a{1, 3} : a가 1개이상 3개이하 있다. (a, aa, aaa) |
{n, } | 앞의 표현식이 n개 이상있다,. | a{1, } : a가 1개이상 있다, (a, aa, aaa, ... ) |
? | 앞의 표현식이 없거나 한개만 있다. | 010-? : - 가 있거나 없다 (010-, 010) |
* | 앞의 표현식이 없거나 여러개가 있다. | 010-* : -가 여러개있거나 없다 (010, 010-, 010--, ... ) |
+ | 앞의 표현식이 1개 이상있다 | 010-+ : -가 여러개있다 (010-, 010--, 010---, ... ) |
기호 | 설명 |
\d | 0 ~ 9 사이의 숫자 : [0-9] 와 동일 |
\D | 0 ~9 사이의 숫자가 아닌 문자 : [^0-9] 와 동일 |
\w | 알파벳, 숫자, "_" 인 문자 : [0-9a-zA-Z_] 와 동일 |
\W | 알파벳, 숫자, "_" 가 아닌 문자 : [^0-9a-zA-Z_] 와 동일 |
\s | 공백인 문자 |
\S | 공백이 아닌 문자 |
"\" 문자는 이스케이프문자를 사용해야합니다. 따라서 "\d" 정규식을 사용할때에는 "\\d" 라고 작성해야합니다.
어디에서 사용할까?
IDE의 자동완성을 기면 매개변수를 확인할 수 있습니다. 'String regex' 라고 되어있는 매개변수는 정규표현식을 사용할 수 있습니다.
String 정규식 문법
String 클래스에서 지원하는 정규식 메소드는 3가지가 있습니다.
메서드 | 반환타입 | 설명 |
matches (String regex) | boolean | 문자열이 정규식에 매칭되는 값인지 확인 |
replaceAll (String regex, String repacement) | String | 문자열내에 정규식에 매칭되는 문자열을 replacement 문자열로 치환 |
split (String regex) | String[] | 정규식에 매칭되는 문자열을 구분자로 사용하여 분할 |
1. boolean matches (String regex)
String test = "1234567890";
boolean matches = test.matches("[0-9]+"); // 숫자로만 이루어진 문자열인지 확인
System.out.println(matches); // true
2. String replaceAll (String regex, String repacement)
String test = "test123asd,.-;";
String replaceAll = test.replaceAll("[0-9]", "A"); // 모든 숫자를 A로 치환
System.out.println(replaceAll); // testAAAasd,.-;
3. String[] split (String regex)
String test = "a0b1c";
String[] split = test.split("[0-9]"); // 숫자를 구분자로 사용
System.out.println(split[0]); // a
System.out.println(split[1]); // b
System.out.println(split[2]); // c
Pattern
Pattern static compile(String regex) 을 사용하여 정규식 패턴으로 변환해줍니다.
Pattern 객체로 컴파일된 정규식은 Matcher에서 사용됩니다.
String regexString = "([0-9]+)";
Pattern p = Pattern.compile(regexString); // 정규표현식을 정규식패턴으로 컴파일
String.matches()와 같이 Pattern.matches() 를 사용할 수 있습니다.
String regex = "([0-9]+)"; // 숫자로만 이루어져있는지 확인하는 정규표현식
String test= "1234567890";
boolean matches = Pattern.matches(regex, test);
System.out.println(matches); // true
String test2 = "a1234567890";
boolean matches2 = Pattern.matches(regex, test2);
System.out.println(matches2); // false
Matcher
String regexString = "[0-9]{2}"; // 숫자로 이루어진 2자리 문자열
Pattern p = Pattern.compile(regexString); // 정규식 패턴으로 변환
String test = "1a23456"; // 비교할 문자열
Matcher m = p.matcher(test); // 패턴과 비교하여 결과를 Matcher 객체로 반환
while (m.find()) { // 매칭된 결과가 있는지 확인
System.out.println(m.group()); // 결과가 있으면 매칭된 부분 반환
// 결과 : 23
// 결과 : 45
}
반환타입 | 메서드 | 설명 |
find() | boolean | 패턴과 일치하는 문자열이 있을경우 true, 없으면 false |
group() | String | 매칭된 문자열을 반환 |
group(int group) | String | 매칭된 여러 그룹중 int group 번째 문자열 반환 |
groupCount() | int | 매칭된 그룹의 개수 반환 |
matches() | boolean | 전체 문자열과 일치할경우 true, 일치하지 않으면 false |
start() | int | 매칭된 문자열의 시작 인덱스 반환 |
end() | int | 매칭된 문자열의 끝 인덱스 반환 |
start() 와 end()
String regexString = "하세";
Pattern p = Pattern.compile(regexString);
String test = "안녕하세요";
Matcher m = p.matcher(test);
System.out.println(m.find()); // true
System.out.println("문자열 위치 : " + m.start() + " ~ " + m.end()); // 문자열 위치 : 2 ~ 4
* 눈치 채신분들도 계시겠지만 매칭된 문자열을 반환하기전에 find() 메서드를 사용하는걸 볼 수 있습니다. 그럼 만약 find() 메서드를 사용하지 않으면 어떻게 될까요?
매칭결과를 얻기전에 항상 find() 메서드가 선행되어야합니다. 그렇지 않으면 문자열을 반환하는 시점에 IllegalStateException 예외가 발생합니다.
잘못된것이 있으면 언제든 지적해주세요!
'Language > JAVA' 카테고리의 다른 글
[JAVA] String의 불변성(immutability) (0) | 2024.09.23 |
---|---|
[JAVA] 함수형 인터페이스에 대해서 알아보자 (0) | 2024.09.15 |
[JAVA] Collection List를 최적화해보자 (0) | 2024.03.18 |
[JAVA] 직렬화(Serialization)와 역직렬화(Deserialization) (0) | 2024.02.14 |
[JAVA] 제네릭(Generic) 이란? (0) | 2024.01.10 |