본문 바로가기
Java

[Regex] 정규 표현식

by Jayson Jeong 2024. 5. 5.

 

목차

  1. 정규 표현식 패턴
  2. Pattern 클래스와 Matcher 클래스의 사용법
  3. 다양한 정규 표현식

 

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 class의 replaceAll 메서드
String Class의 matches 메서드
Pattern Class의 matches 메서드

 

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/