正则能检查外形,不能替日历作判断

有人请 ChatGPT 写“验证日期的正则”,往往把“长得像日期”和“真有这一天”混为一谈。本文把输入规定为四位年份、两位月份、两位日期,以连字符分隔,如 2026-02-28。这是本站自拟教学场景,不能直接作为所有业务的日期规范。

日期校验:先格式,后真实日历。01 / 固定输入外形:YYYY-MM-DD,使用 re.fullmatch,2026-2-8 不符合两位月日;02 / 日期对象检查:date.fromisoformat 解析年月日,2026-02-30 格式通过但日期不存在;03 / 报错分开说明:类型错误/格式不符/日期无效,让用户知道该更正哪一层;04 / 业务约束另加:截止日期、时区、空值由场景定义,本文只检查纯日期
四个自拟输入 · 正则匹配不是有效性证明。本站原创教学图,非模型实测截图。查看大图 ↗

第一关:整串匹配固定格式

在 Python 里可用 re.fullmatch(r"[0-9]{4}-[0-9]{2}-[0-9]{2}", text)。fullmatch要求整个字符串符合,而不是从文本中找到一段。这里用[0-9]明确限定ASCII数字;若业务接受其他数字字符,应重新定义规则。2026-2-8 因缺少两位月份和日期而失败;2026-02-30 则通过这一关,但它仍不是有效日期。

不要因为第二个输入被正则接受,就在文章或程序里说“日期验证通过”。这一步只验证格式,下一步才验证年月日组合。

第二关:解析成日期对象

格式通过后,用 datetime.date.fromisoformat(text) 解析,并捕获 ValueError。按上面的固定格式,2026-02-28可解析;2026-02-30会抛错,因为二月没有30日。若输入已经经过其他转换,仍要检查实际传入解析器的字符串是否就是原文,不要偷偷替用户“修正”日期。

日期是否落在业务允许的范围又是第三个问题。例如截止日期不能早于今天,这需要单独按时区与业务规则比较,不能让格式正则猜测。某个业务若允许空日期,应把空值处理放在输入校验层,而不是随意让正则匹配空串。

一份清晰的参考流程

先保存原始text。若不是字符串,返回“输入类型不对”;若正则不整串匹配,返回“请用YYYY-MM-DD”;否则尝试date.fromisoformat。成功时返回日期对象,失败时报告“日期不存在或不受支持”。不要在错误信息里重复提交者的全部私人输入。

在本站的 Python 3.9.6 环境里,三个例子分别得到有效、日期无效、格式不符,另用空字符串检查格式失败。这是本地参考代码验证,未声称模型或线上表单已经按此校验。

审阅模型写的表达式

问它使用 search、match 还是 fullmatch;是否只接受两位月日;通过正则后如何验证实际日期;遇到闰年和空值怎么办。若模型写出一条极长的正则声称已覆盖所有日历规则,更应要求最小可运行样例,并优先把格式和日历有效性分两步。

把“格式错误”“日期不存在”“超出业务范围”写成不同反馈,使用者才知道该改哪个地方。项目里若有时区或本地化日期写法,再明确转换边界;本文示例只处理纯日期,没有时刻与时区。