목차
- 정규 표현식 패턴
- Pattern 클래스와 Matcher 클래스의 사용법
- 다양한 정규 표현식
1. 정규 표현식의 패턴
1.1. 그룹과 범위(Group and Range)
패턴 | 설명 | 예시 |
| | 또는 | [a-z|A-Z] //소문자 또는 대문자 [0-9|a-z] //숫자 또는 소문자 |
() | 그룹 | (\\w+) //문자(특수문자 제외)로만 이루어진 문자열 (\\d{1,3}) //1이상 3이하인 길이의 숫자로만 이루어진 문자열 ([a-z]+)([0-9]{1,5}) //소문자로만 이루어진 문자열 그룹1, 1이상 5이하의 길이의 숫자로만 이루어진 문자열 그룹2 |
[] | 괄호 안의 어떤 문자든 | [0-9\\s-] //숫자 또는 공백 또는 '-' 괄호 안에서 '.' 은 패턴이 아닌 단순 문자로 인식 |
[^] | 괄호 안의 어떤 문자가 아닐 때 | [^\\w] // 문자가 아닌 경우만 [^0-9] //숫자가 아닌 경우만 [^\s] //공백 문자 또는 탭이 아닌 경우만 |
1.2. 문자 클래스(Character Classes)
패턴 | 설명 | 예시 |
. | 줄바꿈을 제외한 모든 문자열 | (.+) //줄바꿈을 제외한 모든 문자로 이루어진 문자열 |
- | 문자의 범위 지정 | 0-9 //0부터 9사이 a-z, A-Z //소문자 또는 대문자 ㄱ-ㅎ, 가-힣 //한글 범위 |
\\w | 문자만 허용 = [a-z|A-Z|0-9] | (\\w+) //문자로만 이루어진 문자열 |
\\W | 문자가 아닌 경우에만 허용 = [^\\w] | (\\w+) //특수문자(공백 포함)로만 이루어진 문자열 |
\\d | 숫자만 허용 = [0-9] | (\\d+) //숫자로만 이루어진 문자열 (\\d{1,5}) //숫자로만 이루어진 문자열 중 1부터 최대 5개 까지 |
\\D | 숫자가 아닌 경우에만 허용 = [^0-9] | (\\D+) //숫자가 아닌 문자(특수문자 포함)로만 이루어진 문자열 |
\\s | 공백 문자 or 탭 인 경우 = [\t\n\x0B\f\r] | (\\s+) //공백문자로만 이루어진 문자열 |
\\S | 공백 문자 or 탭이 아닌 경우 = [^\s] | (\\S+) //공백문자가 아닌 문자로만 이루어진 문자열 |
1.3. 수량자(Quantifier)
패턴 | 설명 | 예시 |
? | zero or one, 없거나 있거나 | |
* | zero or more, 없거나 있거나 많거나 = {0,} |
|
+ | one or more, 하나 또는 많이, + 앞에 설정된 조건이 더 이상 일치하지 않을 때까지 일치한 모든 값을 적용 = {1,} |
([0-9]+), (\\d+) // 숫자로만 이루어진 문자열 |
{n} | n 개가 있는 경우만 | ([0-9] {2}) //숫자로만 이루어진 문자가 2개일 경우만 |
{n,} | n 개 이상 일 경우만 | ([0-9] {3,}) //숫자로만 이루어진 문자가 3개 이상일 경우만 |
{n,m} | 최소 n개, 최대 m개 탐색 | ([0-9] {2,5}) //숫자로만 이루어진 문자가 2개 이상, 5개 이하일 경우만 |
※탐욕 수량자(Greedy Match), 게으른 수량자(Lazy, Non-greed Match)
1.4. 경계(Boundary Matchers)
패턴 | 설명 | 예시 |
^ | 문장의 시작 | |
$ | 문장의 끝 | |
\b | 단어의 경계 | (\b[a-z]) ([0-9]\b) |
\B | 단어의 경계가 아님 | (\B[a-z]) |
2. Pattern 클래스와 Matcher 클래스의 사용법
2.1. Pattern Class
메소드 | 내용 |
compile(String regex) | 입력한 정규 표현식을 갖는 패턴을 생성 |
pattern() | 컴파일된 정규표현식을 String 형태로 반환 |
matches(String regex, CharSequence input) | 정규 표현식과 문자열이 일치하는지 확인 true or false 반환 |
matcher(CharSequence input) | 패턴에 매칭할 문자열을 입력하여 Matcher 생성 및 반환 |
split(CharSequence input) | 패턴이 일치하는 항목을 중심으로 input을 분할 |
asPredicate() | 문자열을 일치시키는데 사용할 수 있는 술어을 반환 |
2.2. Matcher Class
메소드 | 내용 |
Pattern pattern() | matcher가 적용한 패턴을 반환 |
Matcher usePattern(Pattern newPattern) | matcher가 사용할 패턴을 반환 |
Matcher reset(CharSequence input) | matcher가 분석할 문자열을 변경 |
boolean find() | 패턴이 일치하는 문자열을 찾는다. 찾는 문자열이 있다면 true |
boolean find(int start) | start 인덱스 이후부터 패턴이 일치하는 문자열을 찾는다. |
boolean matches() | 패턴에 전체 문자열이 일치한 경우 true를 반환 |
String group() | 매치와 일치하는 문자열 그룹 전체를 반환 |
String group(int group) | 매치와 일치하는 문자열 중 gruop번째 그룹의 문자열을 반환 group(0) = group() |
String group(String name) | 매칭되는 문자열 중 해당 name을 지정한 그룹의 문자열을 반환 |
int groupCount() | 패턴 내의 그룹 개수를 반환 |
int start() | 매칭하는 문자열의 시작 인덱스를 반환 |
int start(int group) | 매칭하는 문자열 중 group 번째의 문자열의 시작 인덱스를 반환 start(0) = start() |
int start(String name) | 매칭하는 문자열 중 name이 일치하는 그룹의 시작 인덱스를 반환 |
int end() | 일치하는 문자열의 마지막 문자열 이후 인덱스를 반환 = 다음 그룹의 start()와 동일 |
int end(int group) | 매칭 문자열 중 group 번째 그룹의 마지막 문자열 이후 인덱스를 반환 |
int end(String name) | 매칭 문자열 중 name이 일치하는 그룹의 마지막 문자열 이후 인덱스를 반환 |
String replaceAll(String replacement) | 패턴과 일치하는 모든 문자열을 지정된 replacement로 변경 |
입력한 문자열이 원하는 조건과 일치하는지 확인
//방법 1
String data = "abcdefgh";
boolean result = data.matches("^[a-z0-9]{6,12}$");
//방법 2
String data = "abcdefgh";
boolean result = Pattern.matches("^[a-z0-9]{6,12}$", data);
//방법 3
Pattern p = Pattern.compile("^[a-z0-9]{6,12}$");
Matcher m = p.matcher(data);
boolean result = m.matches();
정규 표현식의 조건과 일치하는 문자열 출력
Pattern p = Pattern.compile("정규표현식");
Matcher m = p.matcher("데이터");
if(m.find())
String result = m.group();
else
일치하는 결과 없음
//문자열의 특정 범위만 찾을 때 예시
//그룹 1 : 문자열의 소문자 또는 대문자가 종료되는 지점까지 출력
//그룹 2 : 문자열의 소문자 또는 대문자가 종료되고 숫자가 나오는 지점부터 최대 5개 까지만 출력
String data = "adasds1234fasd2jnd";
String data = "asbf12342898jnd";
Pattern p = Pattern.compile("([a-zA-Z]+)([0-9]{1,5})");
Matcher m = p.matcher(data);
m.find();
String result = m.group();
"adasds1234fasd2jnd" → "adasds1234"
"asbf12342898jnd" → "asbf12342"
2.4. 정규 표현식의 성능 개선
String의 replaceAll()이나 matches(), 또는 Pattern의 matches를 사용할 때 마다 Pattern.compile() 메서드를 통해서 새로운 Pattern 객체가 생성된다.
이렇게 생성된 객체는 한 번 사용하고 버려지기 때문에 GC의 대상이 된다.
한 번만 사용하는 정규 표현식이라면 상관 없겠지만 자주 사용하는 정규 표현식이라면 사용할 때마다 GC 처리가 필요해지기 때문에 비효율적이다.
자주 사용하는 정규 표현식이라면 Pattern을 한 번만 생성해 놓고 재활용하면 된다.
public class Sample(){
private Pattern p = Pattern.compile("^[a-z0-9]{6,12}$");
public boolean someting(String str){
return p.matcher(str).matches();
}
//또는
private Matcher m = Pattern.compile("^[a-z0-9]{6,12}$").matcher("");
public boolean someting(String str){
return m.reset(str).matches();
}
}
3. 다양한 정규표현식
3.1. 문자열 검증
// 빈 값이 아니고 소문자나 대문자만 허용
String regex = "^[a-zA-Z]+$";
// 빈 값이 아니고 소문자만 허용
String regex = "^[a-z]+$";
// 빈 값이 아니고 대문자만 허용
String regex = "^[A-Z]+$";
//빈 값이 아니고 숫자만 허용
String regex = "^[0-9]+$";
// 빈 값이 아니고 한글만 허용(모음만 있는 것은 허용 안됨)
String regex = "^[ㄱ-ㅎ|가-힣]+$";
//특수 문자가 아닌 문자만 허용(한글, 공백도 허용 안됨)
String regex = "^[\\w]+$";
3.2. 이메일, 아이디, 패스워드, 주민등록번호 검증
//이메일 - 하이픈(-), 언더바(_)를 포함하는 이메일 검증 test@test.com 형식
String regex = "^[\\w-]+@[a-zA-Z]+[.][a-z]+$"; // 언더바(_), 하이픈(-) 제외
//이메일 - 하이픈(-), 언더바(_) 포함 이메일 검증, test@test.com 형식, test@test.co.kr 형식 모두 적용
String regex = "^[\w-]+@[a-zA-Z]+[.]([a-z]+[.]{0,1}[a-z]+)$";
//사용자 아이디 - 영문 숫자 조합 6~12자리
String regex = "^[a-z0-9]{6,12}$";
// 사용자 아이디 - 영문 숫자 조합 6~12자리, 첫 문자는 소문자만 가능
String regex = "^[a-z]{1}[a-z0-9]{5,11}$";
//패스워드 - 대소문자 + 숫자 + 특수문자(!@#$%^*+=-)를 각각 한 개 이상씩 포함한 10~16자리
String regex = "^(?=.*[a-zA-Z])(?=.*[!@#$%^*+=-])(?=.*[0-9]).{10,16}$";
//전화번호 - 숫자만 11자리와 12자리
String regex = "^[0-9]{11,12}$";
//전화번호 - 하이픈(-)이 포함된 10 ~ 11자리 번호 허용 ex) 010-1234-5678
String regex = "^([0-9]{3})-([0-9]{3,4})-([0-9]{4})+$";
//전화번호 - 하이픈이(-)이 포함된 9 ~ 11자리 번호 허용 ex) 02-123-4567
String regex = "^([0-9]{3})-([0-9]{3,4})-([0-9]{4})+$"
//전화번호 - 국제번호가 포함된 전화번호 정규식 ex) +82-10-1234-5678
String regex = "^\\+82-10-([0-9]{3,4})-([0-9]{4})+$";
//주민등록번호 - 뒷자리 첫 숫자가 1 ~ 4 사이의 주민등록번호 허용
String regex = "^[0-9]{6}-[1-4][0-9]{6}$";
3.3. 날짜 검증
//날짜 - yyyy-MM-dd 적용
String regex = "^[\\d]{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$";
//날짜 - yyyy/MM/dd 적용
String regex = "^[\\d]{4}]\\/(0[1-9]|1[012])\\/(0[1-9]|[12][0-9]|3[01])$";
//날짜 - 특정 연도 범위만 허용, yyyy-MM-dd 적용
String regex = "^(19|20)[0-9]{2}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$";
//시간 - HH24:mm 적용
String regex = "^([1-9]|[01][0-9]|2[0-3]):([0-5][0-9])$";
Reference.
오라클의 자바 정규 표현식 문서 - https://docs.oracle.com/javase/tutorial/essential/regex/index.html
정규 표현식 테스트 사이트 - https://regexr.com/
'Java' 카테고리의 다른 글
[Thread] 뮤텍스, 세마포어, 모니터의 스레드 동기화와 구현 예제 (0) | 2023.06.20 |
---|---|
[Spring Batch] 한 개의 Step에 여러 개의 Processor의 다중 적용이 필요할 경우(CompositeProcessor, 예제 포함) (0) | 2023.01.18 |
[Spring Batch]#6 스프링 배치 Item Reader (0) | 2023.01.17 |
[Thymeleaf] 타임리프 유틸 함수 - #strings, #arrays 등등 (0) | 2022.10.05 |
[Spring Batch] #4 스프링 배치 Step 과 Tasklet (0) | 2022.09.27 |