如何用正则匹配(\d月|\d日)后到串尾的最短子串且不包含起始匹配词
正则提取目标子串实现方案
问题根因
之前尝试的所有正则写法,默认匹配的都是字符串中第一个出现的\d月|\d日片段,没有满足返回子串长度最短的要求。要拿到最短的目标后缀,本质是需要定位到字符串里最后一次出现\d月|\d日的位置,截取该匹配段结束后到字符串末尾的内容即可。
可行实现
方案1:纯正则贪婪匹配写法
利用正则默认的贪婪匹配特性,直接定位到最后一个符合规则的日期片段,捕获其后的所有内容:
import re str1 = "秋天9月9日长江工程完成" str2 = "秋天9月9日9日长江工程完成" # 正则规则 pattern = r'.*(?:\d月|\d日)(.*)' print(re.search(pattern, str1).group(1)) # 输出:长江工程完成 print(re.search(pattern, str2).group(1)) # 输出:长江工程完成
规则说明:
- 开头的
.*为贪婪匹配模式,会尽可能向后匹配字符,直到碰到字符串中最后一个满足\d月|\d日的片段才停止,保证定位到最靠后的日期标记 (?:\d月|\d日)为非捕获组,匹配最后一个日期片段,本身不会作为单独结果返回- 末尾的
(.*)捕获日期片段结束后到字符串末尾的所有内容,即为目标结果
方案2:匹配位置切片写法
逻辑更直观,先拿到所有匹配\d月|\d日的位置,取最后一个匹配的结束下标直接对原字符串切片,容错性更高:
import re def extract_target_suffix(content: str) -> str: all_matches = list(re.finditer(r'\d月|\d日', content)) # 无匹配场景可按需调整返回值 if not all_matches: return "" last_match_end_pos = all_matches[-1].end() return content[last_match_end_pos:] # 测试 str1 = "秋天9月9日长江工程完成" str2 = "秋天9月9日9日长江工程完成" print(extract_target_suffix(str1)) # 输出:长江工程完成 print(extract_target_suffix(str2)) # 输出:长江工程完成
之前写法错误说明
r'(\d月|\d日).*':从第一个匹配的日期片段开始截取,会包含后续的其他日期片段,不符合要求- 带负向前瞻的两种写法:本质还是在定位第一个出现的日期片段,没有找到最靠后的匹配位置,因此只能返回
9月这类错误结果
内容的提问来源于stack exchange,提问作者4daJKong
相关产品推荐
相关产品推荐

