You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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. 捕获组的使用:把需要保留的前缀部分用()包裹为捕获组,替换时用\1直接引用该组内容,避免在替换字符串中使用正则元字符。
  2. 修正数字匹配规则:将\d*改为\d+,确保匹配至少一个数字,符合需求描述。
  3. 转义年份字符串:用re.escape(current_year)处理当前年份,防止年份中包含正则特殊字符(规范写法)。
  4. 批量测试用例:将所有测试用例放入列表遍历,一次性验证所有场景。

运行修改后的代码即可得到预期输出。


内容的提问来源于stack exchange,提问作者Matt095

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 04:55:24