Python正则re.sub移除重复当前年份遇报错,求正确实现方案
问题解决:Python正则替换
re.error: bad escape \d错误修复及需求实现 问题背景
编写Python代码意图实现:当文本中[XX -- XX]格式后已指定一个年份时,移除末尾的当前年份。给出多组输入示例与期望输出,但使用re.sub执行替换时触发re.error: bad escape \d at position 2错误,需修正替换逻辑以得到预期结果。
原代码
import re, datetime #Example input cases input_text = '[26 -- 31] de 10 del 200 de 2022' #example 1 input_text = '[26 -- 31] de 12 del 206 del 2022' #example 2 input_text = '[06 -- 11] del 09 del ano 2020 del 2022' #example 3 input_text = '[06 -- 06] del mes 09 del ano 20 del ano 2022' #example 4 input_text = '[16 -- 06] del mes 09 del 2022' #example 5 (not modify) possible_year_num = r"\d*" #I need one or more numbers (one or more numeric digits but never any number) current_year = datetime.datetime.today().strftime('%Y') month_context_regex = r"[\s|]*(?:del[\s|]*mes|de[\s|]*el[\s|]*mes|de[\s|]*mes|del|de[\s|]*el|de)[\s|]*" year_context_regex = r"[\s|]*(?:del[\s|]*año|de[\s|]*el[\s|]*año|de[\s|]*año|del[\s|]*ano|de[\s|]*el[\s|]*ano|de[\s|]*ano|del|de[\s|]*el|de)[\s|]*" #I combine those modular regex expressions to build a regex that serves to identify the substring in which the replacement must be performed identity_replacement_case_regex = r"\[\d{2}" + " -- " + r"\d{2}]" + month_context_regex + r"\d{2}" + year_context_regex + possible_year_num + year_context_regex + current_year #Only in this cases, I need replace with re.sub() and obtain this output string, for example 1, '[26 -- 31] de 10 del 200' replacement_without_current_year = r"\[\d{2}" + " -- " + r"\d{2}]" + month_context_regex + r"\d{2}" + year_context_regex + possible_year_num input_text = re.sub(identity_replacement_case_regex, replacement_without_current_year, input_text) print(repr(input_text)) # --> output
预期输出
'[26 -- 31] de 10 del 200' #for example 1 '[26 -- 31] de 12 del 206' #for example 2 '[06 -- 11] del 09 del ano 2020' #for example 3 '[06 -- 06] del mes 09 del ano 20' #for example 4 '[16 -- 06] del mes 09 del 2022' #for example 5 (not modified)
报错信息
Traceback (most recent call last): input_text_substring = re.sub(identity_replacement_case_regex, replacement_without_current_year, input_text_substring) raise s.error('bad escape %s' % this, len(this)) re.error: bad escape \d at position 2
错误原因及解决方案
错误原因
你在re.sub的替换字符串中直接使用了\d这类正则元字符,但替换字符串并非正则表达式,其中的\会被视为普通转义符,Python无法识别\d作为合法转义序列,因此抛出错误。
正确实现方式
核心解决思路是在匹配正则中使用捕获组,替换时通过组编号引用捕获到的内容,而非重复编写正则逻辑。同时修正原正则中的匹配规则漏洞:
import re, datetime # 测试用例列表 test_cases = [ '[26 -- 31] de 10 del 200 de 2022', # example 1 '[26 -- 31] de 12 del 206 del 2022', # example 2 '[06 -- 11] del 09 del ano 2020 del 2022', # example 3 '[06 -- 06] del mes 09 del ano 20 del ano 2022', # example 4 '[16 -- 06] del mes 09 del 2022' # example 5 (不修改) ] current_year = datetime.datetime.today().strftime('%Y') possible_year_num = r"\d+" # 修正:匹配一个或多个数字(原\d*会匹配0个数字,不符合需求) month_context_regex = r"[\s|]*(?:del[\s]*mes|de[\s]*el[\s]*mes|de[\s]*mes|del|de[\s]*el|de)[\s]*" year_context_regex = r"[\s|]*(?:del[\s]*(?:año|ano)|de[\s]*el[\s]*(?:año|ano)|de[\s]*(?:año|ano)|del|de[\s]*el|de)[\s]*" # 构建带捕获组的匹配正则:将需要保留的部分用()包裹 identity_replacement_case_regex = ( r"(\[\d{2} -- \d{2}]" + month_context_regex + r"\d{2}" + year_context_regex + possible_year_num + r")" + year_context_regex + re.escape(current_year) # 转义当前年份,避免特殊字符干扰 ) # 替换时直接引用第一个捕获组的内容 for input_text in test_cases: result = re.sub(identity_replacement_case_regex, r"\1", input_text) print(repr(result))
代码说明
- 捕获组的使用:把需要保留的前缀部分用
()包裹为捕获组,替换时用\1直接引用该组内容,避免在替换字符串中使用正则元字符。 - 修正数字匹配规则:将
\d*改为\d+,确保匹配至少一个数字,符合需求描述。 - 转义年份字符串:用
re.escape(current_year)处理当前年份,防止年份中包含正则特殊字符(规范写法)。 - 批量测试用例:将所有测试用例放入列表遍历,一次性验证所有场景。
运行修改后的代码即可得到预期输出。
内容的提问来源于stack exchange,提问作者Matt095
相关产品推荐
相关产品推荐

