화요일의 정규식 3주차 문제는 날짜와 시간 형식을 확인하는 정규식입니다. 거의 숫자로만 구성되어 있어서 어렵지 않게 접근할 수 있을 것입니다. 주의할만한 부분이라면 "숫자의 유효 범위"를 정규식으로 정해주는 부분입니다. 예를 들어 월(month)은 두 자리 정수라는 간단한 규칙을 따르면서 동시에 01부터 12까지만 가능하다는 제약도 있습니다. 이런 부분에 주의한다면 어렵지 않게 접근할 수 있을 듯 합니다.
문제의 조건은 다음과 같습니다.
- 문자열은 YYYY/MM/DD HH:MM(:SS) 형식을 따른다. (괄호는 생략 가능하다는 뜻)
- 연도는 1000년부터 2012년까지
- 윤달은 고려하지 않으며, 매달은 30일까지 있다고 가정한다.
매칭되어야 하는 문자열
2012/09/18 12:10 2001/09/30 23:59:11 1995/12/01 12:12:12 1001/01/07 14:27 2010/10/20 10:10 2000/01/01 01:01:01 2007/07/22 22:34:59 2010/05/05 00:00:00
매칭되지 않아야 하는 문자열
2012/9/18 23:40 2013/09/09 09:09 2012/00/01 01:49:59 2012/13/25 22:17:00 1994/11/00 12:12 2012/12/4 12:12 2009/11/11 24:00:00 2012/06/24 13:60 2002/10/10 14:59:60 a2011/11/11 11:11:11 2005/05/05 05:05:05d
해답 및 풀이
[toggle txt_show="3주차 풀이 보기" txt_hide="3주차 풀이 감추기"]해답
/^(1\d{3}|200\d|201[0-2])\/(0[1-9]|1[0-2])\/(0[1-9]|[1-2]\d|30) (2[0-3]|[0-1]\d)(:[0-5]\d){1,2}$/
풀이
먼저 연도를 생각해보겠습니다. 연도는 1000년부터 시작하므로 항상 4자리 숫자일 것입니다. 1000부터 1999년까지는 모두 가능한 숫자이므로 1000년대의 규칙은 1\d{3}
으로 만들 수 있습니다. 2000년대에서 2100년은 불가능한 숫자이므로 시작은 앞의 두 자리는 항상 20으로 시작할 것입니다. 2000~2009년까지는 모두 가능하므로 200\d
, 2010~2012까지만 가능하므로 201[0-2]
로 표현할 수 있습니다. 앞서 만든 세 가지를 모두 합치면 년도 규칙 (1\d{3}|200\d|201[0-2])
이 완성됩니다.
정규표현식에서 슬래시(/)는 특수한 의미(정규식 시작과 끝)를 가지므로 문자 그대로의 '/'를 사용하려면 앞에 백 슬래시를 추가해 이스케이프 해줘야 합니다.
월(month)과 일(day)은 00이 아닌 01부터 시작하는 두 자리 숫자입니다. 이 부분에만 주의하면 앞서 연도를 만들었던 규칙과 비슷한 과정을 통해 만들 수 있습니다. 이런 규칙에 따르면 00부터 23까지 가능한 시(hour) 부분도 어렵지 않게 만들 수 있습니다.
분(minute)과 초(second)는 모두 00부터 59까지의 숫자라는 공통된 범위가 있습니다. 그리고 초는 생략될 수 있으므로 분 또는 초에 해당하는 규칙이 1개(초가 없는 경우) 또는 2개(초가 있는 경우)가 가능하다고 작성하면 됩니다.
[/toggle]