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

如何仅在捕获组间含;或.\n时使用re.sub()执行替换?

问题需求

仅当**日期格式(\d{4}-\d{2}-\d{2})与指定时间短语(含pasado|despues|tras + 数字 + dias|dia及变体)**这两个捕获组之间存在至少一个;或.\n时,才使用Python的re.sub()执行替换操作。


现有代码

import re, datetime

# 需要执行替换的示例输入
input_text = "Decian muchas cosas; Seguro eso ocurrira despues de 3 dias"
input_text = "seguro eso ocurrira despues de 3 dias.\n empieza el 2021-11-12"
input_text = "Recien el 2021-10-12; seguro eso ocurrira despues de 3 dias."

# 不需要执行替换的示例输入
input_text = "seguro eso ocurrira despues de 3 dias. empieza el 2021-11-12"
input_text = "Recien el 2021-10-12, seguro eso ocurrira despues 3 dias."

# 日期加减函数
def add_or_subtract_days(datestr, days, operation):
    today = datetime.date.today()
    if   operation == "add" : x = (datetime.datetime.strptime(str(today), "%Y-%m-%d") + datetime.timedelta(days=int(days))).strftime('%Y-%m-%d')
    elif operation == "subtract" : x = (datetime.datetime.strptime(str(today), "%Y-%m-%d") - datetime.timedelta(days=int(days))).strftime('%Y-%m-%d')
    return x

some_text = r"[\s|]*" 

input_text = re.sub(r"(?:([12]\d{3}-[01]\d-[0-3]\d)(\D*?)|)" + some_text + r"(?:(?:pasados|pasado|despues del|despues de el|despues de|despues|tras) (\d+) (?:días|día|dias|dia)|(\d+) (?:días|día|dias|dia) (?:pasados|pasado|despues del|despues de el|despues de|despues|tras))" + some_text + r"(?:([12]\d{3}-[01]\d-[0-3]\d)(\D*?)|)",
                lambda m: print(m[3]) ,
                #lambda m: add_or_subtract_days(  m[1] or m[4] , m[2] or m[3] , "add" ),
                input_text)

print("output: " + repr(input_text)) # 输出结果

期望输出(当前日期为2022-12-13时)

"Decian muchas cosas; Seguro eso ocurrira 2022-12-16"
"seguro eso ocurrira 2022-12-16.\n empieza el 2021-11-12"
"Recien el 2021-10-12; seguro eso ocurrira despues de 2022-12-16."

以下两个示例不执行替换,因为捕获组之间没有;或.\n
"seguro eso ocurrira despues de 3 dias. empieza el 2021-11-12"
"Recien el 2021-10-12, seguro eso ocurrira despues de 3 dias."

修正后的代码

import re, datetime

def add_or_subtract_days(days, operation):
    # 固定当前日期为示例中的2022-12-13,实际使用可替换为datetime.date.today()
    today = datetime.date(2022, 12, 13)
    if operation == "add":
        return (today + datetime.timedelta(days=int(days))).strftime('%Y-%m-%d')
    elif operation == "subtract":
        return (today - datetime.timedelta(days=int(days))).strftime('%Y-%m-%d')

def replace_matches(match):
    # 获取匹配到的天数
    days = match.group(2) or match.group(5)
    if not days:
        return match.group(0)
    # 计算目标日期
    target_date = add_or_subtract_days(days, "add")
    # 根据匹配的模式替换对应的短语部分
    if match.group(1):
        # 日期在前,短语在后的情况,保留日期和分隔符,替换短语为目标日期
        return f"{match.group(1)}{match.group(3)}{target_date}"
    else:
        # 短语在前,日期在后的情况,替换短语为目标日期,保留分隔符和后面的内容
        return f"{match.group(4)}{target_date}{match.group(6)}"

# 测试所有示例输入
test_cases = [
    "Decian muchas cosas; Seguro eso ocurrira despues de 3 dias",
    "seguro eso ocurrira despues de 3 dias.\n empieza el 2021-11-12",
    "Recien el 2021-10-12; seguro eso ocurrira despues de 3 dias.",
    # 不需要替换的示例
    "seguro eso ocurrira despues de 3 dias. empieza el 2021-11-12",
    "Recien el 2021-10-12, seguro eso ocurrira despues 3 dias."
]

# 正则表达式:匹配两种情况,且日期和短语之间必须包含;或.\n
pattern = r"""
    # 情况1:日期在前,短语在后,中间有;或.\n
    (([12]\d{3}-[01]\d-[0-3]\d))
    (.*?(?:;|\.\n).*?)
    ((?:pasados|pasado|despues del|despues de el|despues de|despues|tras) (\d+) (?:días|día|dias|dia))
    |
    # 情况2:短语在前,日期在后,中间有;或.\n
    ((?:pasados|pasado|despues del|despues de el|despues de|despues|tras) (\d+) (?:días|día|dias|dia))
    (.*?(?:;|\.\n).*?)
    (([12]\d{3}-[01]\d-[0-3]\d))
"""

for text in test_cases:
    result = re.sub(pattern, replace_matches, text, flags=re.VERBOSE)
    print(repr(result))

关键修改说明

  1. 正则表达式优化:

    • 拆分两种匹配场景:日期在前短语在后、短语在前日期在后
    • 强制要求两者之间的内容包含;或.\n,用(.*?(?:;|\.\n).*?)捕获分隔部分
    • 使用re.VERBOSE模式提升正则可读性
  2. 日期函数修复:

    • 修正原代码中strptime的参数错误(date对象需转为字符串)
    • 示例中固定为2022-12-13方便验证,实际使用可替换为datetime.date.today()
  3. 替换逻辑优化:

    • 自定义替换函数replace_matches,根据不同匹配场景精准替换目标短语为计算后的日期
    • 保留原文本中的分隔符和其他内容,确保替换后文本结构不变

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 23:10:45