Python正则表达式提取日期:如何单独分离年份?
解决日期格式提取的正则匹配问题
这个问题的核心是正则表达式的匹配优先级问题——你的原正则会优先尝试匹配month和day组,哪怕输入是单独的年份,它也会硬把年份拆成前两位(month)和后两位(year)。要解决这个问题,我们需要按日期格式的完整性从高到低设置匹配分支,让正则先尝试匹配最完整的格式,匹配不到再尝试更简单的格式。
修正后的正则表达式方案
我们把三种日期格式按优先级排序,用|分隔(正则分支是从左到右匹配,匹配成功就停止):
- 完整的
MM/DD/YYYY或MM/DD/YY格式 - 仅
MM/YYYY格式 - 仅
YYYY格式
对应的正则表达式如下:
pattern = r'(?P<month>\d{1,2})/(?P<day>\d{1,2})/(?P<year>\d{2,4})|(?P<month>\d{1,2})/(?P<year>\d{4})|(?P<year>\d{4})'
完整代码示例
import pandas as pd # 测试数据 sr = pd.Series(['04/20/2009', '04/20/09', '4/20/09', '4/3/09', '6/2008','12/2009','2010']) # 提取日期字段 extracted = sr.str.extract(pattern) # 查看结果 print(extracted)
运行后输出的结果会是:
month year day 0 04 2009 20 1 04 09 20 2 4 09 20 3 4 09 3 4 6 2008 NaN 5 12 2009 NaN 6 NaN 2010 NaN
可以看到,单独的2010正确匹配到了year字段,没有被拆分成month和year;6/2008也正确识别了month和year,day字段为空,完全符合预期。
可选:统一转换为标准日期格式
如果需要把提取的字段转换成标准的datetime类型,可以用pd.to_datetime自动处理两位年份(比如09会默认转换为2009):
# 生成日期字符串 date_strings = extracted.apply( lambda row: f"{row['month']}/{row['day']}/{row['year']}" if pd.notna(row['day']) else f"{row['month']}/{row['year']}" if pd.notna(row['month']) else row['year'], axis=1 ) # 转换为datetime extracted['standard_date'] = pd.to_datetime(date_strings, yearfirst=False, errors='coerce') print(extracted[['standard_date']])
这样就能得到统一的日期格式了。
内容的提问来源于stack exchange,提问作者Bluetail




