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

Python正则re.sub批量追加文本仅替换奇数项的解决方法

问题描述

我有如下格式的多行字符串:

Front

(A) Text1.

(A) Text2.

(A) Text3.

(A) Text4.

(A) Text5.

End

注意:Text1、Text2等文本可能包含换行符。我希望在每个Text1、Text2等文本末尾追加字符串END。

用变量c表示上述多行字符串,我尝试使用正则re.sub实现该操作:

c = re.sub("\(A\)(.*?)\n\n\(A\)" , r"(A)\1 END\n\n(A)", c, flags=re.DOTALL)

但该操作仅替换了奇数序号的项,输出结果如下:

Front

(A) Text1. END

(A) Text2.

(A) Text3. END

(A) Text4.

(A) Text5.

End

最后一个项目可作为例外处理,我更关注为何仅每隔一个项目末尾追加了END。我认为原因是当第二个(A)被用作re.sub的匹配终点时,Python会将其排除在起始匹配点之外。请问该如何解决这个问题?

问题原因

你的判断完全正确。原正则\(A\)(.*?)\n\n\(A\)会匹配(A) TextX.加上后续空行和下一个(A),完成一次替换后,下一次匹配的起始位置会落在第二个(A)之后,直接跳过了中间的条目,所以只会处理奇数位置的内容。

解决方法

方案1:用正向预查避免消耗匹配内容

把正则里的第二个(A)改成正向预查,它不会被计入匹配的消耗部分,下一次匹配可以从这个位置重新开始。修改后的代码如下:

import re

c = re.sub(r"\(A\)(.*?)(?=\n\n\(A\))", r"(A)\1 END", c, flags=re.DOTALL)

这里的(?=\n\n\(A\))是正向预查,只检查后面是否存在\n\n(A),但不会把这部分内容包含在匹配结果里,这样所有中间的(A)条目都会被处理。

方案2:统一处理所有(A)条目(包括最后一个)

如果想要连最后一个(A) Text5.也一起处理,可以调整正则,匹配所有以(A)开头,直到下一个(A)或者End前的内容:

import re

c = re.sub(r"\(A\)(.*?)(?=\n\n\(A\)|\n\nEnd)", r"(A)\1 END", c, flags=re.DOTALL)

这个正则的(?=\n\n\(A\)|\n\nEnd)表示匹配到后面是\n\n(A)或者\n\nEnd的位置,这样所有(A)开头的条目都会被追加END。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 06:45:27