정규표현식은 String을 다루는데 아주 중요한 역할을 하고 있다.
일정한 패턴으로 쏟아지는 정보 중 필요로 하는 정보만 쏙 빼온 다던지, 내가 원하는 패턴으로 정보들이 들어오는지 확인하는 등 여러가지로 사용되어 질 수 있다.
이 글에서는 Java에서 정규표현식을 사용하는 간단한 방법을 얘기해보려고 한다.
먼저, 아래와 같은 URL이 있다.
https://some.domain.com/token/randomstringtoken?params=true
위 URL에서 token에 해당하는 randomstringtoken 을 정규표현식을 사용해 추출 해보도록 하겠다.
먼저 randomstringtoken의 규칙을 먼저 파악해보자
randomstringtoken 모두 소문자인 영문이면서 token/ 과 ? 사이에 오는 문자열임을 알 수 있다.
이를 정규표현식으로 나타 내면 아래처럼 나타 낼 수 있다.
token\/([a-z]+)\?
위 정규 표현식은 3부분으로 나눌 수 있는데 먼저 token\/ 부분은 token/ 이라는 문자를 찾는 의미 이다.
"/" 를 "\/" 로 표현한 이유는 "/" 문자가 정규표현식에서 사용되는 문자이기 때문에 이스케이프가 필요해서 이다.
다음 부분은 ([a-z]+) 부분이다.
먼저 안쪽 부터 [a-z] 는 a 부터 z 까지 문자 범위를 나타 낸다. 따라서 a, b, c, d, ... z 범위에 있는 문자가 모두 필터링된다고 보면 된다.
그다음 + 는 앞에 정의한 문자 필터 조건이 만족하는 범위까지 연결된 문자를 모두 포함한다는 의미이다.
예를 들어, "abc123" 라는 문자열을 [a-z] 로 필터링 하면 a 만 찾을 수 있는데 [a-z]+ 로 필터링 하게 되면 앞에 있는 조건을 만족하면서 연결된 문자열인 abc를 찾을 수 있다.
그리고 가장 바깥에 있는 "( )" 괄호는 정규표현식에서 사용되는 그룹에 대한 개념을 나타낸 것이다.
이 그룹을 사용해 내가 찾고자 하는 문자열에만 접근할 수 있다.
위 정규표현식에서는 그룹이 총 2개가 생겨난다.
1번째 그룹은 정규표현식을 만족하는 전체 String이 되고 2번째 그룹은 내가 괄호를 사용해 그룹으로 지정한 부분의 String이 된다.
그리고 마지막 부분 "\?" 은 ? 문자를 찾는 의미이다. 마찬가지로 ? 또한 정규표현식에서 사용되는 문자이기 때문에 이스케이프가 필요하다.
정리해보면 해당 정규표현식은 token/으로 시작하면서 ?로 끝나는 문자열을 찾아 가운데 있는 영문 소문자로 이뤄지는 문자열을 그룹으로 묶는 의미를 갖고 있다.
정규표현식의 Test는 아래 Site에서 할 수 있다.
이제 이를 Java를 사용해 구현해보도록 하겠다.
바로 구현한 코드를 보자.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
...
String url = "https://some.domain.com/token/randomstringtoken?params=true";
Pattern pattern = Pattern.compile("token\/([a-z]+)\?");
Matcher matcher = pattern.matcher(url);
matcher.find();
String token = matcher.group(1) // "randomstringtoken"
Java에서는 내장되어있는 정규표현식 모듈을 사용한다.
Pattern은 정규표현식 pattern 을 정의하는 객체이고, Matcher는 pattern을 사용해 필터링하고자 하는 string 매칭 등을 할 수 있는 객체 이다.
실제로 정규표현식 pattern 이 대상 String에 적용되려면 matcher.find() 를 실행해줘야 한다.
해당 메소드는 Boolean을 반환하는데 해당 패턴에 맞는 문자열을 찾은 경우 true 를 반환한다.
그다음에 matcher.group(1) 을하게 되면 앞서 지정했던 1번 그룹으 token string 을 가져올 수 있다.
만약 matcher.group(0)을 하게 되면 token/randomstringtoken? 과 같이 패턴으로 일치되는 모든 String 이 반환된다.
Java에서는 group 뿐만 아니라 replace와 같은 여러가지 메소드들도 지원하고 있다.
때에 따라서 적절히 사용하면 좋겠다.