日期正则表达式

从文本里找日期用的模式,捕获分组已经写好,可以直接拿去用。原则先说清楚:正则认外形,日期库验日历。一个“知道”二月只有二十八天的正则,通常也已经没人读得懂。

🎙️ 发布并录制于: ·

ISO 写法与斜杠写法

格式由你自己定的时候,优先用年、月、日这个顺序。它排序天然正确,也省掉了各地习惯之间的争论。代码需要分开拿到年月日,就把三段数字各自用一对括号包起来,捕获分组会按顺序把它们返回给你。斜杠写法本身就带着歧义:同一个值在波士顿和伦敦是两个不同的日子,所以顺序只能由数据约定来定,正则定不了。

\b\d{4}-\d{2}-\d{2}\b

# with capture groups — year, month, day come back separately:
(\d{4})-(\d{2})-(\d{2})

# Python
m = re.search(r"(\d{4})-(\d{2})-(\d{2})", text)
year, month, day = m.groups()      # ("2026", "07", "22")
\b\d{1,2}/\d{1,2}/\d{4}\b          # both DD/MM and MM/DD shapes

# the regex CANNOT tell you which one it is. 04/07/2026 is
# July 4th in Boston and April 7th in London. only context
# (or the data's spec) knows. no pattern fixes ambiguity.
真实故障现象
如果导入进来的生日,凡是号数在 1 到 12 之间的都正好差一个月,问题不在正则。是数据来源和解析代码对“先日后月”还是“先月后日”的理解不一致。把来源格式明确记下来,再按这个声明的格式去解析。

日志、时间戳和月份名称

日期埋在一堆乱文本里的时候,正则才真正值钱。在日志里,把日期和时间分成两个捕获分组,或者干脆把搜索锚定到每一行的开头。英文月份名必须写成一份明确的候选列表,不然普通单词也会被当成日期认错。

# classic log line:  2026-07-22 14:30:07,123 ERROR ...
(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})

# grep all of yesterday's errors from a log:
grep -E "^2026-07-21 .*ERROR" app.log

# time on its own (24h):
\b([01]?\d|2[0-3]):[0-5]\d\b        # 9:05, 14:30 — rejects 25:99
\b(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z]* \d{1,2},? \d{4}\b

# matches "Jul 22, 2026", "July 22 2026", "Dec 3, 1999"

日历交给日期解析器验证

外形对得上,日子仍然可能根本不存在。不要去教正则闰年和每月有多少天。先用正则把候选字符串找出来,再交给日期库逐个解析。解析器抛出的真实错误本身就是有用的线索;只有当跳过坏候选真的是你想要的行为时,才去捕获这个异常。

正则应该停在哪里
两位数的月份会把 1399 一并收下。你可以把这个范围限死,可它照样接受 2 月 30 日。诚实的分工是:正则找候选,日期解析器做验证。在 Python 里,datetime.strptime 会抛出 ValueError: day is out of range for month;该做的是修数据源或者丢掉这个候选,而不是继续把正则写长。
# the find-then-parse pattern (Python):
for m in re.finditer(r"\b\d{4}-\d{2}-\d{2}\b", text):
    try:
        d = datetime.strptime(m.group(), "%Y-%m-%d")
    except ValueError:
        continue            # shaped like a date, isn't one (2026-13-45)
直接建议
如果你处理的是格式已知的结构化数据,比如 API 的某个字段或规范里写明的 CSV 列,那就跳过正则,直接按声明的格式调日期解析器。正则的地盘是日期藏在日志、邮件和抓取页面里的时候。
📚 本页属于正则表达式系列。五个核心概念、贪婪匹配的坑,以及何时干脆不用正则,均配音频:10 分钟学会正则表达式 →

Tell me what missed

A correction is more useful than a compliment. This goes straight to the person who writes SwiftGrasp.

Was this page useful?
0/1000

Please do not include passwords, private keys, or personal information.