앎을 경계하기

DAFIT/905 - 정규표현식

<DAFIT> 05 Regular Expression 02 - 날짜

양갱맨 2019. 11. 18. 03:05

문제를 보니 날짜가 될 수 없는 데이터는 변하지 않고 올바른 날짜인 경우에만 REPLACEDATE로 치환하는 문제다.

날짜가 될 수 없는 조건은 다음과 같다.

1. month = 0이하 13이상

2. day = 0이하 32이상

* 2월의 경우 day = 0이하 30이상

 

정규표현식을 사용할 수 있는 파이썬 라이브러리 re를 추가한다.

import re

테스트케이스는 다음과 같이 구성하였다.

testcase = ["2019.02.30","2019.06.41","2019.13.30","2000.00.01","2019-06-06", "2019/06/06", "2019.06.06", 
            "19.06.06", "6/6", "06/13", "06월 3일", "6월 23일"]

 

테스트케이스 중 날짜가 되지 않는 데이터만 골라낸다.

정규표현식을 작성해보자.

YYYY.MM.DD 형태이니까

연도는 [0-9]가 4번 연속되어야한다.

구분자는 .을 사용하기때문에 [.]으로 표현한다.

첫 번째 기준인 month에 대해서 표현한다.

[0-9]{4}[.]00[.].* : 00월인 경우를 체크한다.

[0-9]{4}[.]1[3-9].* : 13-19월인 경우,

[0-9]{4}[.][2-9][0-9].* : 20-99월인 경우를 체크한다.

[0-9]{4}[.][0-9]{3,}.* : 월이 3자리 이상인 경우를 체크한다.

다음은 day에 대해서 표현해보자.

[0-9]{4}[.].*[.]00 : 00일인 경우이다.

[0-9]{4}[.]0?2[.]29 : 02 또는 2월일 때 29일인 경우이다.

[0-9]{4}[.]0?2[.][3-9][0-9] : 02 또는 2월일 때 30-99일인 경우이다.

[0-9]{4}[.]0?2[.][0-9]{3,} : 02 또는 2월일 때 day가 세자리 이상인 경우

[0-9]{4}[.].*[.]3[2-9] : 32일 ~ 39일인 경우

[0-9]{4}[.].*[.][4-9].* : 40-99일의 경우

[0-9]{4}[.].*[.][0-9]{3,} : day가 세자리 이상인 경우

p = '[0-9]{4}[.]00[.].*|[0-9]{4}[.]1[3-9].*|[0-9]{4}[.][2-9][0-9].*|\
     [0-9]{4}[.][0-9]{3,}.*|[0-9]{4}[.].*[.]00|\
     [0-9]{4}[.]0?2[.]29|[0-9]{4}[.]0?2[.][3-9][0-9]|[0-9]{4}[.]0?2[.][0-9]{3,}|\
     [0-9]{4}[.].*[.]3[2-9]|[0-9]{4}[.].*[.][4-9][0-9]|[0-9]{4}[.].*[.][0-9]{3,}'

p = re.compile(p)

 

결과를 저장할 배열을 만들고

테스트케이스마다 정규표현식을 적용했을때 매치가 되면(제대로 된 날짜가 아닌 경우) 치환하지않고 그대로 그 값을 저장하고 매치가 안되면 제대로 된 날짜로 간주하여 결과[testcase index]에 "REPLACEDATE"를 저장한다.

result=[]
for idx in range(len(testcase)):
    case = testcase[idx]
    m = p.match(case)
    if m:
        result.append(m.group())
    else:
        result.append("REPLACEDATE")

* 이 코드에서는 구분자를 .으로만 사용한 제대로 된 날짜가 아닌 경우만 검색한다.

'DAFIT > 905 - 정규표현식' 카테고리의 다른 글

<DAFIT> 05 Regular Expression 01 - 전화번호  (0) 2019.11.18