(?:^(GET|POST) ([^?]+)[?]?(.*) (HTTP/(0.9|1.0|1.1))$) 이 정규식이 내가 원하는 데이터를 추출 할 수 있는 정규식이다. 간단히 해석을 해보면
(): 캡춰할 영역
^: 문자열 시작
$: 문자열 종료
|: 둘중 하나
^(GET|POST): 문자열의 시작이 GET이나 POST로 시작하고 이영역은 내가 캡춰하길 원하는 영역
[]: 문자 클래스지정 ^: 문자 클래스 내에서의 ^기호는 제외의 의미다
?: 수량 0 또는 1
+: 수량 1이상 (1 또는 more)
*: 수량 없을 수도 있고 무한정 많을 수도 있다.(0 또는 more)
.: 모든 문자셋
([^?]+)[?]?(.*): 앞쪽은 ?문자를 제외한 문자열이 하나이상 반복되고 이 영역은 내가 캡춰하길 원하는 영역, ?문자는 0 또는 1이며 뒷쪽은 모든 문자가들어갈 수 있으며 내가 캡춰하길 원하는 영역
HTTP/(0.9|1.0|1.1)$: HTTP/0.9, HTTP/1.0, HTTP/1.1 이라는 문자열
자 아래는 이문자열을 파싱하기 위한 테스트 프로그램이다.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TestReg {
Pattern pattern = Pattern.compile("(?:^(GET|POST) ([^?]+)[?]?(.*) (HTTP/(0.9|1.0|1.1))$)");
public static void main(String[] args) {
TestReg reg = new TestReg();
String line = "POST /tomcat-docs/images/tomcat.gif?userid=admin HTTP/0.9";
reg.testRun(line);
}
public void testRun(String line) {
Matcher matches = pattern.matcher(line);
if (matches.find()) {
System.out.println("Match find");
System.out.println("Method: " + matches.replaceAll("$1"));
System.out.println("URL: " + matches.replaceAll("$2"));
System.out.println("Param: " + matches.replaceAll("$3"));
System.out.println("Version: " + matches.replaceAll("$4"));
}
}
}
정규식을 compile하여 Pattern을 작성하고 Pattern.matcher()함수에 인자로 검사할 문자열을 입력한다.
그 결과물로 Matcher가 나오는데 Matcher.find()함수는 찾은 문자열이 있을 경우 true를 반환한다.
Matcher.replaceAll() 함수에 "$1", "$2"와 같은 인자들은 캡춰할 데이터 영역을 지정하는 것이다.
위에 보는것과 같이 정규식을 이해하는데에 대한 노력을 조금만 하면 실제로 코드는 굉장히 짧아지게 되며 속도 또한 스트링 비교나 StringTokenizer를 사용하는것보다 훨씬 빠른것을 알 수 있다.
정규식에 관한 정보는 http://www.pcre.org에
서 찾아 볼 수 있다. pcre는 perl에 호환되는 정규 표현식을 c 라이브러리로 만드는 프로젝트이다. 물론 JAVA에서
사용되는 정규식과는 조금은 다른 표현이 있기는 하지만 크게 다르지 않고 과거부터 지금까지 가장 많이 사용되었고 사용되고 있는
표현식이므로 반드시 읽고 익히도록 하자
출처 : Developer Story