자바, 올바르게 정규식 패턴 사용하기
서론
자바에서 정규식을 사용할때 java.util.regex.Pattern 을 자주 사용합니다. Pattern 클래스를 이용한 정규식을 잘 못사용하면 성능이 많이 떨어질 수 있습니다. 따라서, 올바른 Pattern 클래스의 사용법에 대해서 배워보겠습니다.
잘 못된 사용 방법
private final String PHONE = "^\\d{3}-\\d{3,4}-\\d{4}$";if(!Pattern.matches(PHONE, "010-1234-1234")) {
// 생략
}
Pattern 의 matches 메서드를 보면 다음과 같이 되어있습니다.
/**
* Compiles the given regular expression and attempts to match the given
* input against it.
*
* <p> An invocation of this convenience method of the form
*
* <blockquote><pre>
* Pattern.matches(regex, input);</pre></blockquote>
*
* behaves in exactly the same way as the expression
*
* <blockquote><pre>
* Pattern.compile(regex).matcher(input).matches()</pre></blockquote>
*
* <p> If a pattern is to be used multiple times, compiling it once and reusing
* it will be more efficient than invoking this method each time. </p>
*
* @param regex
* The expression to be compiled
*
* @param input
* The character sequence to be matched
*
* @throws PatternSyntaxException
* If the expression's syntax is invalid
*/
public static boolean matches(String regex, CharSequence input) {
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(input);
return m.matches();
}
메서드에서 매번 static 메서드인 compile 을 돌린 후 Matcher 를 생성하는 것을 볼 수 있습니다. matches 메서드의 주석에는 다음과 같은 문구가 적혀있습니다.
If a pattern is to be used multiple times, compiling it once and reusing
* it will be more efficient than invoking this method each time.
패턴을 여러 번 사용하는 경우 한 번 컴파일한 후 재사용
* 매번 이 메서드를 호출하는 것보다 효율적입니다.
보통 우리는 패턴을 만들고 한 번만 사용할 지라도, 나중에는 여러번 사용할 가능성도 있기 때문에 주석에 나와있는 내용 처럼 컴파일 후 재사용 하는 방식을 선택하는 것이 훨씬 효율적입니다.
올바른 사용 방법
private static final Pattern PHONE = Pattern.compile("^\\d{3}-\\d{4}-\\d{4}$");if(!PHONE.matcher("010-1234-1234").matches()) {
// 생략
}
위 처럼 컴파일 후 재사용하는 방식을 선택하면 Pattern 클래스 사용 시 성능을 끌어올릴 수 있습니다.