任意の文字列がハイフン区切りの年(yyyy)または年月(yyyy-mm)または(yyyy-mm-dd)であるかどうかを検証する正規表現を用意したので以下に残しておく。
まず、個別の正規表現はそれぞれ以下のとおり。
- 年(yyyy):
^\d{4}$
- 年月(yyyy-mm):
^\d{4}-(0[1-9]|1[0-2])$
- 年月日(yyyy-mm-dd):
^(?!([02468][1-35-79]|[13579][013-57-9])00-02-29)((\d{4}-(01|03|05|07|08|10|12)-(0[1-9]|[12]\d|3[01]))|(\d{4}-(04|06|09|11)-(0[1-9]|[12]\d|30))|(\d{4}-02-(0[1-9]|1\d|2[0-8]))|(\d{2}([02468][048]|[13579][26])-02-29))$
よって、求める正規表現は以下のとおり。
^(\d{4}|\d{4}-(0[1-9]|1[0-2])|(?!([02468][1-35-79]|[13579][013-57-9])00-02-29)((\d{4}-(01|03|05|07|08|10|12)-(0[1-9]|[12]\d|3[01]))|(\d{4}-(04|06|09|11)-(0[1-9]|[12]\d|30))|(\d{4}-02-(0[1-9]|1\d|2[0-8]))|(\d{2}([02468][048]|[13579][26])-02-29)))$
テスト
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
import pandas as pd
date_re = re.compile(r'^(\d{4}|\d{4}-(0[1-9]|1[0-2])|(?!([02468][1-35-79]|[13579][013-57-9])00-02-29)((\d{4}-(01|03|05|07|08|10|12)-(0[1-9]|[12]\d|3[01]))|(\d{4}-(04|06|09|11)-(0[1-9]|[12]\d|30))|(\d{4}-02-(0[1-9]|1\d|2[0-8]))|(\d{2}([02468][048]|[13579][26])-02-29)))$')
# 正当な日付に関して検証する。
for date in pd.date_range(start='1800-01-01', end='2200-12-31'):
if date.is_month_start:
if date.is_year_start:
print(date.strftime('%Y'))
assert date_re.search(date.strftime('%Y'))
print(date.strftime('%Y-%m'))
assert date_re.search(date.strftime('%Y-%m'))
print(date.strftime('%Y-%m-%d'))
assert date_re.search(date.strftime('%Y-%m-%d'))
# TODO: 不正な日付に関して検証する。