[Java] 정규표현식
2022. 1. 10. 20:02ㆍLanguage`/Java
정규표현식 (Regular Expression)
특정 규칙을 가진 문자열의 집합을 표현하기 위해 쓰는 형식언어
- ex) 전화번호/민증/이메일 등 정해진 형식이 존재하고, 사용자가 해당 형식을 제대로 입력했는지 검증
- java.util.regex 패키지 안에 있는 Pattern클래스/Matcher클래스 사용
단순 패턴 사용
- 문자열을 있는 그대로 대응
- /abc/ : 문자열에 정확히 'abc'라는 문자들이 순서대로 대응해야 한다
- ex) 'Grab crab' : 'ab c' 문자열을 포함하고 있으나 'abc'에는 대응하지 않기 때문에 X
특수 문자 사용
- 하나 이상의 b를 찾거나, 공백을 찾는것과 같이 특수한 경우
- /ab*c/ : 'a'뒤에 0개 이상의 'b'가 존재
문법 (Regex)
Character
\ | 일반 문자 앞 : 해당 일반 문자는 특별하고, 그대로 해석 X 특수 문자 앞 : 해당 특수 문자는 특별하지 않고, 그대로 해석 O |
\\ | 백슬래시(\) 문자 |
\t | tab(탭) 문자 |
\n | newline 문자(ex. 엔터) |
\r | carriage-return 문자 |
\b | 단어의 경계에 해당 (해당 경계 앞이나 뒤에 어떠한 문자도 있으면 안된다) ex) moon → \bm : 'm'에 대응 → oo\b : 대응 X ('oo'뒤에 'n'이 있기 때문) → oon\b : 'oon'에 대응 |
\B | 단어의 경계가 아닌 부분에 대응 → 두 단어 문자의 사이 → 단어 문자가 아닌 두 문자 사이 → 빈 문자열 |
\d | 숫자 : [0-9]와 동일 |
\D | 숫자를 제외한 모든문자 : [^0-9]와 동일 |
\s | 공백 문자 : [ \t\n\x0B\f\r ] |
\S | 공백이 아닌 문자 : [^\s] |
\w | 알파벳/숫자/_ : [a-zA-Z0-9_] |
\W | 알파벳/숫자/_가 아닌 모든 문자 : [^a-zA-Z0-9_] |
. | 모든 문자 (\제외) |
Character Class
[] | 문자를 하나의 집합으로 묶는다 |
[abc] | a/b/c 전부 가능 (a or b or c) |
[^abc] | a/b/c를 제외한 문자 |
[a-zA-z] | 합집합 : a-z AND A-Z |
[a-z&&[def]] | 교집합 : d, e, f만 가능 |
[a-z&&[^bc]] | 차집합 : a-z에서 bc제외 : [ad-z] |
[a-z&&[^m-p]] | 차집합 : a-z에서 m-p제외 : [a-lq-z] |
Boundary & Quantifiers
^ | 문자열 시작 |
$ | 문자열 종료 |
? | 앞의 표현식이 0번 or 1번 등장 |
* | 앞의 표현식이 0번 이상 반복 |
+ | 앞의 표현식이 1번 이상 반복 |
{n} | n번 반복 |
{n,} | n번 이상 반복 |
{n,m} | 최소 n번, 최대 m번 반복 |
Operator
XY | X뒤에 Y가 존재 |
X|Y | X or Y |
(X) | X를 하나의 그룹으로 묶는다 |
Special Constructs
(x) | x를 하나의 그룹으로 묶는다 → 패턴 x와 일치하는 문자열을 찾고, 그룹 단위로 나누기 → ()없는 경우와 같이 동일한 패턴의 문자열을 찾고 해당하는 문자열을 ()로 나눠 그룹화 → 그룹은 1번부터 번호가 부여된다 → 0번은 패턴과 일치하는 전체 문자열 |
(?<name>x) | x를 name 이름인 하나의 그룹으로 묶는다 |
(?:x) | 캡처하지 않는 그룹 → 해당하는 그룹은 패턴으로써의 역할은 하지만, 캡처는 X |
(?=x) | 앞쪽 문자열을 기준 → /ab(?=c)/ : 뒤가 'c'인 'ab'문자열 탐색 |
(?!x) | 앞쪽 문자열을 기준 → /ab(?!c)/ : 뒤가 'c'가 아닌 'ab'문자열 탐색 |
(?<=x) | 뒤쪽 문자열을 기준 → /(?<=ab)c/ : 앞이 'ab'인 'c'문자열 탐색 |
(?<!x) | 뒤쪽 문자열을 기준 → /(?<!ab)c/ : 앞이 'ab'가 아닌 'c'문자열 탐색 |
자주 사용하는 정규 표현식
정규 표현식 | 의미 | 패턴 종류 |
^[0-9]*$ | ^ : 패턴의 시작 [0-9] : 0 ~ 9사이의 숫자 * : 글자 수 상관하지 않고 검사 $ : 패턴의 종료 |
숫자만 |
^[a-zA-Z]*$ | ^ : 패턴의 시작 [a-zA-Z] : a~z / A~Z사이의 문자 * : 글자 수 상관하지 않고 검사 $ : 패턴의 종료 |
영문자만 |
^[가-힣]*$ | ^ : 패턴의 시작 [가-힣] : 가~힣 사이의 한글 * : 글자 수 상관하지 않고 검사 $ : 패턴의 종료 |
한글만 |
^[a-zA-Z0-9]*$ | ^ : 패턴의 시작 [a-zA-Z0-9] : a~z / A-Z / 0~9사이의 문자 * : 글자 수 상관하지 않고 검사 $ : 패턴의 종료 |
영어 & 숫자만 |
^[a-zA-Z0-9]+@[a-zA-Z0-9]+$ | ^ : 패턴의 시작 [a-zA-Z0-9] : a~z / A-Z / 0~9사이의 문자 + : [a-zA-Z0-9]을 1번 이상 반복 @ : 고정문자 $ : 패턴의 종료 |
이메일 |
^01(?:0|1|[6-9]) - (?:\d{3}|\d{4}) - \d{4}$ | ^ : 패턴의 시작 01(?:0|1|[6-9]) : 01은 고정이고 뒤에 0|1|[6-9] (?:\d{3}|\d{4}) : 가운데 숫자는 3개 or 4개 \d{4} : 끝 숫자는 4개 $ : 패턴의 종료 |
휴대전화번호 |
^\d{2,3} - \d{3,4} - \d{4}$ | 전화번호 |
Pattern 클래스
- 정규 표현식이 컴파일된 클래스
- 정규 표현식에 대상 문자열을 검증/활용
▶ static boolean matches(String regex, CharSequence input)
- regex = 정규식 / input = 대상 문자열
- 대상 문자열과 정규식이 일치하는지 확인
▶ static Pattern compile(String regex)
- 주어진 정규식을 갖는 패턴 생성
▶ Matcher matcher(CharSequence input)
- 패턴에 매칭할 문자열을 입력해서 Matcher 생성
▶ String pattern()
- 컴파일된 정규 표현식 return
▶ String [] split(CharSequence input)
- 패턴이 일치하는 항목을 중심으로 input을 분할
▶ String [] split(CharSequence input, int limit)
- limit-1의 횟수만큼 패턴을 일치시켜서 문자열을 자른다 (문자열 limit개 생성)
Matcher 클래스
- Pattern 클래스를 받아서 대상 문자열과 패턴이 일치하는 부분을 찾거나 전체 일치 여부 판별
▶ boolean matches()
- 패턴에 전체 문자열이 일치한 경우 true
▶ boolean find()
- 패턴이 일치하는 다음 문자열이 있으면 true
▶ boolean find(int start)
- start 인덱스 이후부터 패턴이 일치하는 문자열 찾기
▶ int start()
- 매칭하는 문자열의 시작 인덱스 return
▶ int start(int group)
- 매칭 문자열 중 group번째 문자열의 시작 인덱스 return
- start(0) = start()
▶ int end()
- 일치하는 문자열의 마지막 문자열 이후 인덱스 return
▶ int end(int group)
- 매칭 문자열 중 group번째 그룹의 마지막 문자열 이후 인덱스 return
- end(0) = end()
▶ String group()
- 매칭된 문자열 return
▶ String group(int group)
- 매칭된 부분 중 group번 그룹핑 매칭부분 return
▶ int groupCount()
- 패턴 내 그룹핑한 전체 개수 return
▶ Pattern pattern()
- Matcher가 해석한 패턴 return
▶ Matcher usePattern(Pattern newPattern)
- Matcher가 사용할 pattern 변경
▶ Matcher reset(CharSequence input)
- Matcher가 분석할 문자열 변경
▶ String replaceAll(String replacement)
- 패턴과 일치하는 모든 문자열을 지정된 replacement로 변경