从文本里找日期用的模式,捕获分组已经写好,可以直接拿去用。原则先说清楚:正则认外形,日期库验日历。一个“知道”二月只有二十八天的正则,通常也已经没人读得懂。
🎙️ 发布并录制于: ·
格式由你自己定的时候,优先用年、月、日这个顺序。它排序天然正确,也省掉了各地习惯之间的争论。代码需要分开拿到年月日,就把三段数字各自用一对括号包起来,捕获分组会按顺序把它们返回给你。斜杠写法本身就带着歧义:同一个值在波士顿和伦敦是两个不同的日子,所以顺序只能由数据约定来定,正则定不了。
\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.日期埋在一堆乱文本里的时候,正则才真正值钱。在日志里,把日期和时间分成两个捕获分组,或者干脆把搜索锚定到每一行的开头。英文月份名必须写成一份明确的候选列表,不然普通单词也会被当成日期认错。
# 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"外形对得上,日子仍然可能根本不存在。不要去教正则闰年和每月有多少天。先用正则把候选字符串找出来,再交给日期库逐个解析。解析器抛出的真实错误本身就是有用的线索;只有当跳过坏候选真的是你想要的行为时,才去捕获这个异常。
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)