如何用pandas正则提取文本中所有%yyyy格式年份 解决匹配不全问题
原正则失效原因
原代码无法匹配所有目标年份,核心问题有3点:
- 正则中加了
^锚点,强制从字符串起始位置开始匹配,只能识别文本开头附近的年份,无法匹配出现在文本中间的年份 - 前缀匹配组加了
?限定,最多只能匹配1个非数字前缀字符,遇到括号、多空格、字母前缀(比如c1995里的c)就会匹配失败 - 没有做数字边界校验,既可能漏匹配,也可能把长串数字里的四位片段误识别成年份
修正实现方案
匹配逻辑调整为:识别1900-2099区间(可根据业务需求调整范围)的四位连续数字,要求数字前后不能紧跟其他数字,自动兼容所有非数字类前后缀(包括你提到的c、~、;、括号、点、横杠、冒号、换行符等特殊字符)。
因为你只需要提取四位年份,不需要日月字段,可以直接移除空的day、month捕获组简化逻辑,修正后代码如下:
import pandas as pd # 测试文本,包含你提到的各类特殊前后缀场景 text_list = [ "y1983 Clinic Hospital", ".2010 - wife; nightmares", " shx of TBI (1975)", "TSH okay in 2015", "Esophageal cancer, dx: 2013", "8mo in 2009\n", "2008 partial thyroidecto", "c1995 record", "~2001 data", "2014; case"] s = pd.Series(text_list) # 正则说明: # (?<!\d) 负向后瞻,保证四位数字前侧不是数字 # (?:19|20)\d{2} 匹配1900-2099区间的四位年份,可根据业务调整前缀扩展年份范围 # (?!\d) 负向前瞻,保证四位数字后侧不是数字 result = s.str.extract(r'(?P<year>(?<!\d)(?:19|20)\d{2}(?!\d))') print(result)
运行后输出结果如下,所有测试样例的年份都能被正确提取:
year 0 1983 1 2010 2 1975 3 2015 4 2013 5 2009 6 2008 7 1995 8 2001 9 2014
补充说明
- 如果业务场景中存在四位非年份数字(比如编码、ID号)和年份混淆的情况,可以在正则中补充上下文关键词规则进一步过滤
- 如果需要覆盖更早/更晚的年份,修改
(?:19|20)部分即可,比如要覆盖1800-2099的年份,将该段替换为(?:18|19|20)
内容的提问来源于stack exchange,提问作者paschal
相关产品推荐
相关产品推荐

