정규표현식 018. 하위 표현식 3

조회 수 5033 추천 수 0 2012.01.30 09:16:36

정규식으로 날짜를 검색하는 것은 쉽습니다. 날짜에 해당하는 문자열이 일정한 패턴만 갖고 있다면 말입니다. 가령,


2011-02-29 마누라 생일이다. 이번에는 꼭 까먹지 말아야지.


위의 텍스트에서 날짜만 매치시키려면? 이제는 너무도 쉬운 문제일 것입니다.


\d{4}-\d{2}-\d{2}


위와 같이 하면 됩니다. 물론 \d는 [0-9]로 바꿔 써도 됩니다. 그런데 여기서 날짜 포맷이 잘못됐다면 어떻게 될까요? 가령 위 문제인 2011-02-29처럼 말입니다. 2011년은 윤년이 아니므로 2월이 28일까지만 있습니다. 이처럼 존재할 수 없는 날짜를 빼고 매치한다는 게 가능할까요?


사실 이런 식의 문제를 정규식으로 처리하기에는 한계가 있습니다. 이는 c나 자바, php 등의 프로그래밍 언어로 처리하는 게 훨씬 더 쉽고 효율적입니다. 정규식으로는 혹 가능하다 해도 훨씬 더 어렵고 처리 속도 또한 느릴 수밖에 없습니다.


물론 방금 내드린 문제의 해결이 불가능한 것은 아닙니다. 이해를 쉽게 하기 위해 경우의 수를 좀 좁혀서 생각해 보겠습니다. 무슨 말이냐면, 연도가 2011년과 2012년의 두 가지만 있다고 가정해 보자는 것입니다. 그리고 편의상 월도 2월에만 국한시켜 보겠습니다.


아시다시피 2012년은 윤년입니다. 따라서 연도가 2011이라면 2월은 28일까지만 올 수 있고 2012라면 29까지 올 수 있습니다.


2011-02-28

2011-02-29

2012-02-29


두 번째 줄만 빼고 매치되면 성공입니다. 정규식은 아래와 같습니다.


20((11-02-(([0-1][0-9])|([2][0-8])))|(12-02-(([0-1][0-9])|([2][0-9]))))


으으윽~ 갑자기 골이 아파오면서 눈텡이가 빠질 것 같은... 그렇습니다. 그래서 이런 식의 판단이 들어가는 문제엔 가급적 정규식을 쓰지 않는 게 좋다고 말씀드린 것입니다. 이 정규식을 작성하면서 저도 눈깨나 아팠답니다. 괄호 짝을 맞추느라고 말입니다. 여기서 윤년의 공식을 한번 볼까요?


아시다시피 4로 나눠지면 윤년입니다. 그러나 100으로 나눠지면 평년입니다. 반전이죠? 그런데 반전이 한번 더 있습니다. 400으로 나눠지면 윤년이 된다는 것입니다. 예를 볼까요?


1900년은? 4로 나눠지지만 100으로 나눠지고 400의 배수는 아니니 평년입니다.

2000년은? 뭐, 더 이상 부연설명이 필요 없겠죠? 윤년입니다.

2010년은? 애초에 4의 배수 자체가 아니니 평년입니다.

2012년은? 4의 배수이고 100으로 안 나눠지므로 윤년입니다.


이를 php 코드로 만들어 볼까요?


<?php

function isLeap($y) {

$b = 0; // 윤년 여부를 나타내는 플래그.


if (($year % 4) == 0) {

$b = 1; // 4로 나눠지면 일단 윤년.


if (($year % 100) == 0) {

$b = 0; // 100으로 나눠지면 평년.


if (($year % 400) == 0)

$b = 1; // 400으로 나눠지면 윤년.

}

}


return $b;

}

?>


쉽지요? 프로그래밍을 조금만 해보신 분이라면 금방 만들 수 있는 수준의 코딩입니다. 게다가 얼마나 간결합니까. 한눈에 봐도 이게 뭐 하는 넘인지 필이 팍 오잖아요. 그런데 정규식으로 이런 패턴 매치를 가능케 하는 것은 불가능합니다. 정규식에는 4의 배수인지 아닌지를 판단할 수 있는 연산자나 문법이 없습니다. 그저 온갖 경우의 수를 나열하는 게 고작입니다. 다만 해당 연도가 제한되어 있다면, 즉 경우의 수가 몇 개 안 된다면 억지로라도 정규식을 작성할 수는 있다는 정도입니다.


List of Articles
번호 제목 글쓴이 날짜 조회 수
29 정규표현식 029. 자바스크립트의 정규식 5 마라톤맨 2012-03-28 8880
28 정규표현식 028. 자바스크립트의 정규식 4 마라톤맨 2012-03-09 4663
27 정규표현식 027. 자바스크립트의 정규식 3 마라톤맨 2012-03-02 4836
26 정규표현식 026. 자바스크립트의 정규식 2 마라톤맨 2012-02-27 5523
25 정규표현식 025. 자바스크립트의 정규식 1 마라톤맨 2012-02-22 7074
24 정규표현식 024. 숙제와 답 마라톤맨 2012-02-17 4994
23 정규표현식 023. 정규식의 옵션과 여러 정규식 엔진들 마라톤맨 2012-02-15 19710
22 정규표현식 022. 드라이브명과 디렉토리, 파일명 분리 2 마라톤맨 2012-02-13 10304
21 정규표현식 021. 드라이브명과 디렉토리, 파일명 분리 1 마라톤맨 2012-02-08 7810
20 정규표현식 020. IP 주소 유효성 검사 2 마라톤맨 2012-02-06 6634
19 정규표현식 019. IP 주소 유효성 검사 1 마라톤맨 2012-02-02 57650
» 정규표현식 018. 하위 표현식 3 마라톤맨 2012-01-30 5033
17 정규표현식 017. 하위 표현식 2 마라톤맨 2012-01-27 4122
16 정규표현식 016. 하위 표현식 1 마라톤맨 2012-01-25 5962
15 정규표현식 015. 최대 매치와 최소 매치 2 마라톤맨 2012-01-20 4558
14 정규표현식 014. 최대 매치와 최소 매치 1 마라톤맨 2012-01-18 7978
13 정규표현식 013. 검색할 위치 2 마라톤맨 2012-01-16 4700
12 정규표현식 012. 검색할 위치 1 마라톤맨 2012-01-13 5280
11 정규표현식 011. 검색 문자 개수 지정하기 머니북 2012-01-12 9614
10 정규표현식 010. 웹 서버 설정에도 필요 머니북 2012-01-11 7830