如何编写正则表达式提取文本中的年份?兼容多格式场景处理
提取年份的正则表达式指南
嘿,这个问题问得太实用了——提取年份的正则确实得根据不同格式灵活调整,我来一步步给你拆解清楚,帮你搞定场景1和场景2的兼容问题~
先明确咱们说的两个典型场景
你提到场景1容易处理,我先按日常最常见的情况把两个场景具象化(如果和你的实际场景有出入,随时告诉我调整):
- 场景1:纯4位有效年份:比如
1995、2024,无任何前后缀,是最直接的匹配情况。 - 场景2:非纯数字的年份变体:比如缩写年份
'87、90,带年代后缀的2000s,嵌入在日期中的Dec 2022,或者年份范围里的2018-2023。
场景1的极简正则
如果只需要匹配纯4位有效年份(这里默认限定在1900-2099,毕竟更早或更晚的年份在日常文本里少见),用这个就够了:
\b(?:19|20)\d{2}\b
我给你拆解下每个部分的作用:
\b:匹配单词边界,避免把长数字串里的4位片段当成年份(比如不会匹配12345里的2345)。(?:19|20):非捕获组,限定年份开头是19或20(如果需要覆盖18xx的年份,改成(?:18|19|20)就行)。\d{2}:匹配任意两位数字,凑成完整的4位年份。
同时覆盖场景1和场景2的通用正则
如果要兼容多种年份格式,这个正则能覆盖绝大多数常见情况,不管是纯4位年份还是各种变体:
(?:(?:19|20)\d{2}|'\d{2}|\d{2}s)(?=\s|$|-|/|\.)
同样拆解下:
(?:19|20)\d{2}:对应场景1的纯4位年份。'\d{2}:匹配带单引号的两位缩写年份(比如'99)。\d{2}s:匹配带年代后缀的年份(比如90s、2010s)。(?=\s|$|-|/|\.):正向预查,确保年份后面是空格、文本结尾、连字符、斜杠或句号,避免匹配无关的数字串(比如不会把abc123里的123当成年份)。
如果你的文本里有带日期前缀的年份(比如 May 2022)或日期中的年份(比如 2023-04-15),可以用这个增强版:
(?:(?:19|20)\d{2})(?=[-/]\d{2}|\s|$)|(?<=\s)(?:19|20)\d{2}(?=\s|$)|'\d{2}|\d{2}s
它额外适配了日期格式里的年份,比如能从 2023-04-15 里提取出 2023,从 Mar 2021 里提取出 2021。
实际使用示例(以Python为例)
给你举个实际应用的例子,假设你有这段文本:
I was born in '95, started college in 2013, and worked through the 2010s. The project ran from 2018-2022, and we launched v2.0 in May 2024.
用Python的re模块提取所有年份:
import re text = "I was born in '95, started college in 2013, and worked through the 2010s. The project ran from 2018-2022, and we launched v2.0 in May 2024." year_pattern = re.compile(r"(?:(?:19|20)\d{2})(?=[-/]\d{2}|\s|$)|(?<=\s)(?:19|20)\d{2}(?=\s|$)|'\d{2}|\d{2}s") years = year_pattern.findall(text) print(years) # 输出: ["'95", '2013', '2010s', '2018', '2022', '2024']
小Tips
- 如果需要把两位缩写年份转换成4位(比如
'95→1995),提取后做个简单判断就行:比如开头是'的话,年份在00-24之间就加20,25-99就加19。 - 如果你的文本里有中文年份(比如“二〇二四年”),那得单独调整正则,不过上面的正则已经覆盖了英文环境下的绝大多数场景。
内容的提问来源于stack exchange,提问作者Olivia Brown




