정규표현식(Regular Expression, regex) 또는 정규식은 특정한 규칙을 가진 문자열의 집합을 표현하기 위해 쓰이는 형식언어다.
컴퓨터 과학의 정규 언어로부터 유래하였으며 현재 많은 프로그래밍 언어, 텍스트 처리 프로그램, 고급 텍스트 편집기 등이 정규 표현식 기능을 제공한다.
자바의 경우 표준 라이브러리를 통해 제공한다.
정해진 형식이 존재하는 문자열(전화번호, 주민등록번호, 이메일등)의 검증 등에 정규표현식을 사용하면 쉽게 구현할 수 있다.
기호 | 설명 | 예제 |
---|---|---|
. | 임의의 문자 1개를 의미 | .{3} : 문자 3개 (F15,0x0등) |
\w | 알파벳 대소문자, 숫자, 언더바. [a-zA-Z_0-9]와 동일. | |
\d | 모든 ASCII 숫자. [0-9]와 동일 | |
\s | 모든 유니코드 공백 문자. [\t\n\x0B\f\r] | |
\W | \w를 제외한 모든 문자. [^a-zA-Z_0-9] | |
\D | \d를 제외한 모든 문자. [^0-9] | |
\S | \s를 제외한 모든 문자. [^\t\n\x0B\f\r] | |
[ ] | 대괄호 내부의 문자가 있는지 확인 | [ab][cd] : a,b중 한 문자와 c,d중 한 문자 → ac ad bc bd |
[^] | 대괄호 내 ^는 제외를 의미 | [^a-z] : 알파벳 소문자 a부터 z까지를 제외한 모든 문자 |
- | 숫자 또는 문자 사이에서 사용하여 범위를 지정 | [a-z] : 알파벳 소문자 a부터 z까지 하나 [a-z0-9] : 알파벳 소문자 전체,0~9 중 한 문자 |
한글의 경우 /w에 포함되지 않으므로 아래와 같이 따로 작성해주어야 한다.
기호 | 설명 | 예제 |
---|---|---|
[ㄱ-ㅎㅏ-ㅣ] | 한글 자,모음 | |
[가-힣] | 가~힣 까지 한글 |
기호 | 설명 | 예제 |
---|---|---|
^ | 정규식으로 검증하는 문자열의 시작을 의미 | ^a : a로 시작하는 단어 |
$ | 정규식으로 검증하는 문자열의 끝을 의미 | a$ : a로 끝나는 단어 |
\b | 단어의 경계. 문자열의 시작과 끝, 공백, 개행, 탭, 콤마, 구두점, 대시문자 등 | "\bapple\b" : This is an apple (o) This is an pineapple(x) |
\B | \B의 반대 |
기호 | 설명 | 예제 |
---|---|---|
( ) | 괄호 안을 하나의 그룹으로 묶는다. | 01(0|1) : 01뒤에 0 또는 1이 들어간다 → 010(o), 011(o), 012(x) |
\n | 그룹n의 캡쳐를 사용 | "(regex)\s\1"gm → regex regex(o) |
(?: ) | 캡쳐를 사용하지 않는 그룹 |
기호 | 이름 | 설명 |
---|---|---|
X(?=Y) | 긍정형 전방탐색(Positive lookahead) | 뒤에 Y가 오는 X |
X(?!Y) | 부정형 전방탐색(Negative lookahead) | 뒤에 Y가 오지 않는 X |
(?<=Y)X | 긍정형 후방탐색(Positive lookbehind) | Y 다음으로 오는 X |
(?<!Y)X | 부정형 후방탐색(Negative lookbehind) | Y 다음으로 오지 않는 X |
기호 | 설명 | 예시 |
---|---|---|
X* | X가 0개 또는 그 이상 존재 | |
X+ | X가 1개 또는 그 이상 존재 | |
X? | X가 0개 또는 1개 존재 | |
X{n} | X가 정확히 n개 존재 | |
X{n,m} | X가 n개 이상 m개 이하 존재 | |
X{2, } | X가 2개거나 그 이상 존재 |
// 정규식 기호로 전달
Pattern.compile("(?i)([a-z]+)")
// 상수로 전달
Pattern.compile("(^.*$)", Pattern.CASE_INSENSITIVE)
기호 | 상수 | 설명 |
---|---|---|
(?i) | Pattern.CASE_INSENSITIVE | 대소문자를 구분하지 않고 검색 |
(?m) | Pattern.MULTILINE | 문자열의 행이 여러개일 경우 행 별로 구분해서 패턴을 검색 |
(?s) | Pattern.DOTALL | .가 개행문자 까지 포함하는 모든 문자로 매칭 |
(?u) | Pattern.UNICODE_CASE | 유니코드 패턴을 사용 |
리턴 타입 | 메소드 | 설명 |
---|---|---|
static Pattern | compile(String regex) | 주어진 정규식을 갖는 Pattern을 생성 Pattern pattern = Pattern.compile(regex); 형태로 사용 |
String | pattern() | 컴파일된 정규 표현식을 반환 |
Matcher | matcher(CharSequence input) | 패턴에 매칭할 문자열을 입력해 Matcher를 생성 Matcher matcher = pattern.matcher(input); 형태로 사용 |
static boolean | matches(String regex, CharSequence input) | 정규식과 문자열이 일치하는지 확인 |
String[] | split(CharSequence input) | 패턴이 일치하는 항목을 중심으로 input을 분할 |
String[] | split(CharSequence input, int limit) | 위와 동일한 방식으로 문자열을 limit회 만큼 분할(문자열이 limit개 생성) 만약 0이하라면 최대한 많이 적용 |
리턴 타입 | 메소드 | 설명 |
---|---|---|
Pattern | pattern() | matcher가 해석한 패턴을 반환 |
Matcher | usePattern(Pattern newPattern) | matcher가 사용할 Pattern을 변경 |
Matcher | reset(CharSequence input) | matcher가 분석할 문자열을 변경 |
int | start() | 매칭하는 문자열의 시작 인덱스를 반환 |
int | start(int group) | 매칭 문자열 중 group번째 문자열의 시작 인덱스를 반환 0은 그룹의 전체 패턴을 의미 start(0) = start() |
int | start(String name) | 매칭 문자열 중 해당 name을 지정한 그룹의 시작 인덱스를 반환 |
int | end() | 일치하는 문자열의 마지막 문자열 이후 인덱스를 반환 |
int | end(int group) | 매칭 문자열 중 group번째 그룹의 마지막 문자열 이후(+1) 인덱스를 반환 0은 그룹의 전체 패턴을 의미 end(0) = end() |
int | end(String name) | 매칭 문자열 중 해당 name을 지정한 그룹의 마지막 문자열 이후(+1) 인덱스를 반환 |
String | group() | 매치와 일치하는 문자열을 반환 |
String | group(int group) | 매칭되는 문자열 중 group번째 그룹의 문자열 반환 0은 그룹의 전체 패턴을 의미 group(0) = group() |
String | group(String name) | 매칭되는 문자열 중 해당 name을 지정한 그룹의 문자열 반환 |
int | groupCount() | 패턴 내에 그룹핑한 개수를 반환(패턴에 있는 괄호 개수) |
boolean | matches() | 패턴에 전체 문자열이 일치한 경우 true를 반환 |
boolean | find() | 패턴이 일치하는 다음 문자열을 찾는다. 다음 문자열이 있다면 true |
boolean | find(int start) | start 인덱스 이후부터 패턴에 일치하는 문자열을 찾는다 |
String | replaceAll(String replacement) | 패턴과 일치하는 모든 문자열을 지정된 replacement로 변경 |
String regex1 = "^[a-zA-Z]+$"; // 알파벳 대소문자
String regex2 = "^[\\w]+$"; // 알파벳 대소문자, 숫자, 언더바
String input1 = "test TEST";
String input2 = "testTEST";
String input3 = "test 1234";
String input4 = "test1234";
System.out.println(Pattern.matches(regex1, input1)); // false
System.out.println(Pattern.matches(regex1, input2)); // true
System.out.println(Pattern.matches(regex1, input3)); // false
System.out.println(Pattern.matches(regex1, input4)); // false
System.out.println(Pattern.matches(regex2, input1)); // false
System.out.println(Pattern.matches(regex2, input2)); // true
System.out.println(Pattern.matches(regex2, input3)); // false
System.out.println(Pattern.matches(regex2, input4)); // true
String regex = "^[\\S]+$"; // 공백문자를 제외한 모든 문자
String input1 = "test 1234 !@#$";
String input2 = "test1234!@#$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher1 = pattern.matcher(input1);
Matcher matcher2 = pattern.matcher(input2);
System.out.println(pattern.pattern()); // ^[\S]+$
System.out.println(matcher1.pattern()); // ^[\S]+$
System.out.println(matcher1.matches()); // false
System.out.println(matcher2.matches()); // true
String regex1 = "^.*$"; // 임의의 문자(개행문자를 제외한 모든 문자)
String regex2 = "(?s)^.*$"; // 개행문자 포함 모든 문자
String input = "test\n1234\n!@#$";
Pattern pattern1 = Pattern.compile(regex1);
Pattern pattern2 = Pattern.compile(regex2);
Matcher matcher1 = pattern1.matcher(input);
Matcher matcher2 = pattern2.matcher(input);
System.out.println(matcher1.matches()); // false
System.out.println(matcher2.matches()); // true
String regex1 = "([a-zA-Z]+)([0-9]*)([*!@#]?)";
String regex2 = "(?<alphabet>[a-zA-Z]+)(?<digit>[0-9]*)(?<symbol>[*!@#]?)";
String input = "abc0!A999AbC#!";
Pattern pattern1 = Pattern.compile(regex1);
Matcher matcher1 = pattern1.matcher(input);
Pattern pattern2 = Pattern.compile(regex2);
Matcher matcher2 = pattern2.matcher(input);
while(matcher1.find()) { // 일치하는 다음 패턴이 있는동안 반복
System.out.println(matcher1.group());
}
// abc0!
// A999
// AbC#
while(matcher1.find()) { // 일치하는 다음 패턴이 있는동안 반복
System.out.println(matcher1.group(1) + "/" + matcher1.group(2) + "/" + matcher1.group(3));
}
// abc/0/!
// A/999/
// AbC//#
while(matcher1.find()) { // 일치하는 다음 패턴이 있는동안 반복
System.out.println("시작 인덱스: " + matcher1.start(1) + "/" + matcher1.start(2) + "/" + matcher1.start(3));
System.out.println("마지막 인덱스: " + matcher1.end(1) + "/" + matcher1.end(2) + "/" + matcher1.end(3));
System.out.println("");
}
// 시작 인덱스: 0/3/4
// 마지막 인덱스: 3/4/5
//
// 시작 인덱스: 5/6/9
// 마지막 인덱스: 6/9/9
//
// 시작 인덱스: 9/12/12
// 마지막 인덱스: 12/12/13
while(matcher2.find()) { // 일치하는 다음 패턴이 있는동안 반복
System.out.println(matcher2.group("alphabet") + "/" + matcher2.group("digit") + "/" + matcher2.group("symbol"));
}
// // abc/0/!
// // A/999/
// // AbC//#
while(matcher2.find()) { // 일치하는 다음 패턴이 있는동안 반복
System.out.println("시작 인덱스: " + matcher2.start("alphabet") + "/" + matcher2.start("digit") + "/" + matcher2.start("symbol"));
System.out.println("마지막 인덱스: " + matcher2.end("alphabet") + "/" + matcher2.end("digit") + "/" + matcher2.end("symbol"));
System.out.println("");
}
// 시작 인덱스: 0/3/4
// 마지막 인덱스: 3/4/5
//
// 시작 인덱스: 5/6/9
// 마지막 인덱스: 6/9/9
//
// 시작 인덱스: 9/12/12
// 마지막 인덱스: 12/12/13
배워보자 정규표현식! (Regular Expression)
자바 정규식(Regular Expression) 사용법 💯 정리
[Java] Pattern, Matcher Class 사용법과 메소드 정리