Home 자바 정규표현식
Post
Cancel

자바 정규표현식

정규 표현식

특정한 규칙을 가진 문자열의 집합을 표현하는데 사용되는 언어.

자바에서는 정규 표현식을 사용하기 위해 java.util.regex 패키지에 있는 클래스들을 사용한다.

주로 Pattern, Matcher 클래스가 사용된다.

Pattern 클래스

정규식이 컴파일된 클래스로, 문자열에 대한 검증을 수행할 수 있다.

  • static Pattern.compile(String regex)
    • 주어진 정규식을 갖는 패턴을 생성한다.
  • Pattern.pattern()
    • 컴파일된 정규 표현식을 반환한다.
  • Pattern.matcher(String regex, CharSequence input)
    • 대상이 되는 문자열과 정규식이 일치할 경우 true, 아닌 경우 false를 반환한다.
  • Pattern.asPredicate()
    • 문자열을 일치시키는데 사용할 수 있는 술어를 작성한다.
  • Pattern.split(CharSequence input)
    • 문자열을 주어진 인자값 CharSequence 패턴에 따라 분리한다.

Mathcer 클래스

  • Matcher usePattern(Pattern newPattern)
    • matcher가 사용할 Pattern을 변경
  • Matcher reset(CharSequence input)
    • matcher가 분석할 문자열을 변경
  • int start()
    • 매칭하는 문자열의 시작 인덱스를 반환한다.
  • int end()
    • 일치하는 문자열의 마지막 문자열 이후 인덱스를 반환한다.
  • String group()
    • 매치와 일치하는 문자열을 반환한다.
  • boolean mathces()
    • 패턴에 전체 문자열이 일치한 경우 true를 반환한다.
  • boolean find(int start)
    • 패턴이 일치하는 다음 문자열을 찾는다. start 인덱스 이후부터 패턴에 일치하는 문자열을 찾는다.
  • String replaceAll(String replacement)
    • 패턴과 일치하는 모든 문자열을 지정된 replacement로 변경한다.

정규 표현식 문법

문자설명
^문자열의 시작
.임의의 한 문자
$문자열의 끝
*문자가 0번 이상 발생
+문자가 1번 이상 발생
?문자가 0번 혹은 1번 발생
[]문자의 집합 범위 ex) [0-9] 0에서 9까지
()괄호 안의 문자를 하나의 문자로 인식
\s공백 문자
\S공백이 아닌 나머지 문자
\w문자만 허용
\W문자가 아닌 경우만 허용
\d숫자만 허용
\D숫자가 아닌 경우에만 허용
1
String email = "[a-zA-Z0-9]+@[0-9a-zA-z]+\\.[a-z]+$";

위와 같이 이메일 형식을 나타낼 수 있다.

참고

https://www.acmicpc.net/problem/3613

위 문제의 경우를 예로 들어보면 아래와 같다.

String javaCamel = "^[a-z]+(([A-Z])([a-z]*))*$";
//가능 - 대문자 한글자로 된 단어도 허용되고, 대문자로 시작하고 그 뒤 소문자로 된 단어도 허용된다.
//소문자를 *로 없어도 되도록했고, 이를 묶어 대문자가 없는 한 단어의 경우를 체크하기 위함.

String javaCamelX = "^[a-z]+(.*[A-Z])([a-z]*)*$" 
//불가능하다. java_Camel의 경우 Error가 발생해야 하는데 .*로 _를 걸러내지 못하기 때문이다.
//아무 문자를 0회 혹은 그 이상 허용하는데 __나 _ 등을 거를 수 없다.

String javaCamelX2 = "^[a-z]+([A-Z])*([a-z]*)*$" 
//불가능하다. 이 경우 될 것 같이 생겼다. 실제로 javaCamel의 경우 된다.
//하지만 대문자가 여러 개일 경우 원하는 대로 되지 않는다.
//javaCamel => java_camel
//javaCAMEL의 경우는 된다. => java_c_a_m_e_l
//javaCaMel의 경우는 실패한다. => Error!
//java가 ^[a-z]+에서 걸러지고, C에서 [A-Z]*이 걸러지고, a에서 [a-z]*이 걸러진다.
//다음 M에서 ([a-z]*)*로 소문자가 여러 개 올 수 있다에 걸린다. [A-Z]*로 가지 못한다.

위와 같은 경우라면 inputValidate

Pattern, Matcher 활용

Pattern 클래스는 Pattern.compile(regex)를 통해 생성할 수 있고, 컴파일된 패턴을 사용하는 Matcher는 만들어진 객체에 matcher(input) 메서드를 통해 생성한다.

1
2
3
4
5
6
7
8
9
String regex = "^[a-zA-Z]$" //영문자만 존재하는가
String input = "Test String"

boolean match = Pattern.matches(regex, input); //false

Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);

boolean match2 = matcher.matches(); //false

find(), matches()

  • matches(): 정규 표현식과 정확히 일치해야 true 반환.
  • find() : 정규 표현식과 일치하는 부분이 있으면 true 반환.
    • 만약 한 번 true를 반환하고 또 find()를 호출했다면, true를 반환한 부분의 다음 인덱스부터 일치하는 부분을 탐색하게 된다.

Grouping

Matcher에 주어진 input 문자열을 패턴에 맞는지 확인하거나 패턴과 일치하는 문자열을 반복해 추출할 수 있는데, 이때 find() 메소드와 group() 메소드가 사용된다. find() 메소드는 패턴이 일치하는 다음 문자열이 존재한다면 true를 반환하기 때문에 while문을 통해 문자열의 끝까지 조회가 가능하다

1
2
3
4
5
6
7
8
9
Pattern pattern = Pattern.compile("([0-9]+)([SDT])([*#]?)"); 
Matcher matcher = pattern.matcher("1D2S#10S*");
 
while (matcher.find()) { 
	System.out.println(matcher.group()); 
} 
// 1D  
// 2S#  
// 10S*

그룹 사용

1
2
3
4
5
6
7
8
9
Pattern pattern = Pattern.compile("(?<score>[0-9]+)(?<bonus>[SDT])(?<option>[*#]?)");
Matcher matcher = pattern.matcher("1D2S#10S*");

while (matcher.find()) {
	System.out.println(matcher.group("score");
}
// 1
// 2
// 10

참고 포스트

https://adjh54.tistory.com/104

This post is licensed under CC BY 4.0 by the author.

인스턴스 필드가 없는 클래스는 정적으로 공개해야 하는가? (유틸리티 클래스)

애플리케이션 구동 환경이 변하는 것을 고려해보자.