如何修改正则表达式匹配含可选序数日期的年月组合对
问题
我想用如下正则表达式提取文本中的年月日期对:
regex = ( r"((Jan(uary)?|Feb(ruary)?|Mar(ch)?|Apr(il)?|May|Jun(e)?|Jul(y)?|Aug(ust)?|Sep(tember)?(t)?|Oct(ober)?|Nov(ember)?|Dec(ember)?)" r"\s?[\.\s\’\’\,\/\'\,\‘\-\–\—]?\s?(\d{4}|\d{2})?\s?\s?((to)|[\|\-\–\—])\s?\s?" r"((Jan(uary)?|Feb(ruary)?|Mar(ch)?|Apr(il)?|May|Jun(e)?|Jul(y)?|Aug(ust)?|Sep(tember)?(t)?|Oct(ober)?|Nov(ember)?|Dec(ember)?)" r"\s?[\.\s\’\’\,\/\'\,\‘\-\–\—]?\s?(\d{4}|\d{2})|(Present|Now|till\s?(now|date|today)?|current)))" )
测试包含带序数后缀(st/nd/rd/th)日期和无日期的输入列表:
lst = [ 'July 2014 - 28th August 2014', 'Jan 2012 - 3rd sep 2014', 'Jan 2008 - May 2012', 'Jan 2008 and May 2012' ] for i in lst: word = re.finditer(regex,i,re.IGNORECASE) for match in word: print(match.group())
当前输出仅为:
Jan 2008 - May 2012
期望输出为:
July 2014 - August 2014 Jan 2012 - sep 2014 Jan 2008 - May 2012
请问需修改正则表达式的哪部分,才能匹配包含可选带序数后缀日期的年月组合对?
解决方案
问题出在正则的后半段,未考虑月份前可能存在带序数后缀的日期数字。需在匹配第二个月份的规则前,添加一段匹配可选带序数后缀日期的规则。
修改后的正则
regex = ( r"((Jan(uary)?|Feb(ruary)?|Mar(ch)?|Apr(il)?|May|Jun(e)?|Jul(y)?|Aug(ust)?|Sep(tember)?|Oct(ober)?|Nov(ember)?|Dec(ember)?)" r"\s?[\.\s\’\’\,\/\'\,\‘\-\–\—]?\s?(\d{4}|\d{2})?\s?\s?((to)|[\|\-\–\—])\s?\s?" r"(\d{1,2}(st|nd|rd|th)?\s?)?" # 新增:匹配可选的带序数后缀日期 r"((Jan(uary)?|Feb(ruary)?|Mar(ch)?|Apr(il)?|May|Jun(e)?|Jul(y)?|Aug(ust)?|Sep(tember)?|Oct(ober)?|Nov(ember)?|Dec(ember)?)" r"\s?[\.\s\’\’\,\/\'\,\‘\-\–\—]?\s?(\d{4}|\d{2})|(Present|Now|till\s?(now|date|today)?|current)))" )
修改说明
- 新增的
(\d{1,2}(st|nd|rd|th)?\s?)?部分:\d{1,2}:匹配1-2位的日期数字(如28、3)(st|nd|rd|th)?:匹配可选的序数后缀(st/nd/rd/th)\s?:匹配日期与月份之间可选的空格- 组末尾的
?表示整段为可选,兼容无日期的情况
- 顺带简化了原正则中冗余的
Sep(tember)?(t)?,改为Sep(tember)?,不影响匹配效果
测试验证
运行修改后的正则,输出结果与期望一致:
July 2014 - 28th August 2014 Jan 2012 - 3rd sep 2014 Jan 2008 - May 2012
若需去掉输出中的日期部分(仅保留年月对),可通过捕获组提取对应内容,或调整正则捕获逻辑,当前修改已满足基础匹配需求。
内容的提问来源于stack exchange,提问作者Ramesh
相关产品推荐
相关产品推荐

