Python regex模块如何让正则在指定条件下匹配失败并完成替换
Python regex模块匹配替换span标签问题解决
问题复现
环境说明
- Python版本:3.9.6
- regex模块版本:2.5.91
待处理文件内容
1. <span>abc.</span> 2. <span>bcd</span> 3. <span>xyz.</span> 4. <span class="good">abc</span> 5. <span class="good">abc.</span> 6. <span class="good">xyz.</span> 7. <span id="whatever">def.</span> 8. <span id="whatever">xyz.</span> 9. <span class="good" id="whatever">ghi.</span> 10. <span class="bad" id="whatever">jkl.</span> 11. <span id="whatever" class="good">abc.</span>
需求约束
- 仅匹配符合以下所有条件的span行:
- 标签内不含class属性
- 标签内文本末尾带句号
- 标签内文本不是
xyz.
(示例中仅第1、7行符合要求)
- 匹配成功后需捕获:可选存在的
id="xxx"属性、span标签内的文本 - 必须一次性调用
regex.sub()完成全局替换,不符合条件的行不能被修改
问题原因
你之前的正则将class排除分支和id捕获分支写成了互斥的|选择结构,同时文本部分的xyz.排除逻辑触发*SKIP后范围控制不当,导致整体匹配逻辑冲突,全部匹配失败。
解决方案
调整正则结构,将所有排除逻辑优先匹配触发(*SKIP)(*FAIL),再走正常捕获逻辑即可,完整可运行代码如下:
import regex text = """1. <span>abc.</span> 2. <span>bcd</span> 3. <span>xyz.</span> 4. <span class="good">abc</span> 5. <span class="good">abc.</span> 6. <span class="good">xyz.</span> 7. <span id="whatever">def.</span> 8. <span id="whatever">xyz.</span> 9. <span class="good" id="whatever">ghi.</span> 10. <span class="bad" id="whatever">jkl.</span> 11. <span id="whatever" class="good">abc.</span>""" newtext = regex.sub( r'<span(?:.*?class=".*?"(*SKIP)(*FAIL)|( id="[a-z]+?")?)>(?:xyz\.(*SKIP)(*FAIL)|([a-z]+\.))</span>', r'<span class="other"\1>\2</span>', text ) print(newtext)
运行效果
替换后仅第1、7行被修改,其余行保持原样:
1. <span class="other">abc.</span> 2. <span>bcd</span> 3. <span>xyz.</span> 4. <span class="good">abc</span> 5. <span class="good">abc.</span> 6. <span class="good">xyz.</span> 7. <span class="other" id="whatever">def.</span> 8. <span id="whatever">xyz.</span> 9. <span class="good" id="whatever">ghi.</span> 10. <span class="bad" id="whatever">jkl.</span> 11. <span id="whatever" class="good">abc.</span>
正则逻辑说明
- 进入span标签后优先匹配是否存在
class="xxx"属性,存在则直接触发(*SKIP)(*FAIL),跳过该标签不处理 - 无class属性时,尝试捕获可选的id属性到分组1,无id则分组1为空
- 匹配标签内文本时优先判断是否为
xyz.,是则触发(*SKIP)(*FAIL)跳过 - 非
xyz.的文本匹配末尾带句号的小写字母内容,捕获到分组2 - 所有排除条件都不触发的标签才会被替换,自动过滤了文本无句号的行
内容的提问来源于stack exchange,提问作者vr8ce
相关产品推荐
相关产品推荐

