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

第一关:整串匹配固定格式
在 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;是否只接受两位月日;通过正则后如何验证实际日期;遇到闰年和空值怎么办。若模型写出一条极长的正则声称已覆盖所有日历规则,更应要求最小可运行样例,并优先把格式和日历有效性分两步。
把“格式错误”“日期不存在”“超出业务范围”写成不同反馈,使用者才知道该改哪个地方。项目里若有时区或本地化日期写法,再明确转换边界;本文示例只处理纯日期,没有时刻与时区。
