如何用Python正则表达式查找不含特定标签模式的子串集合?
提取合法RGB标签对包裹的文本问题
问题背景
处理带颜色标签的文本,规则如下:
[XXXXXX]是RGB颜色头部标签(6位字符)[-]是颜色结束的尾部标签- 合法标签对是头部标签+内容+尾部标签,内容里不能包含其他头部标签;存在头部标签无对应尾部标签的情况(如示例中的
[000000])
示例文本:
[000000]I am a [FFFFFF]boy[-], and my name is [ABABAB][James][-]
需要提取的合法标签对内容是:boy(对应标签[FFFFFF]和[-])、[James](对应标签[ABABAB]和[-])
原代码及错误结果
原正则表达式尝试匹配标签对,但错误地将其他头部标签包含到内容中:
import re p_general_tag = re.compile('(\[\S{6}\])(.+?)(\[\-\])') text = "[000000]I am a [FFFFFF]boy[-], and my name is [ABABAB][James][-]" matched_texts = p_general_tag.findall(text) print(matched_texts)
错误输出:
[('[000000]', 'I am a [FFFFFF]boy', '[-]'), ('[ABABAB]', '[James]', '[-]')]
可以看到第一个匹配的group2包含了[FFFFFF]这个头部标签,不符合需求。
修正方案
问题出在原正则的(.+?)会匹配任意字符(包括头部标签),需要修改为匹配不包含头部标签的内容。可以用负向预查来限制内容里不能出现[XXXXXX]格式的头部标签:
修正后的代码:
import re # 使用负向预查,确保内容中不包含新的RGB头部标签 p_general_tag = re.compile(r'(\[\S{6}\])(((?!\[\S{6}\]).)+?)(\[\-\])') text = "[000000]I am a [FFFFFF]boy[-], and my name is [ABABAB][James][-]" matched_texts = p_general_tag.findall(text) # 提取需要的组(group1是头部标签,group2是内容,group4是尾部标签) result = [(item[0], item[1], item[3]) for item in matched_texts] print(result)
输出结果:
[('[FFFFFF]', 'boy', '[-]'), ('[ABABAB]', '[James]', '[-]')]
正则规则解释
(\[\S{6}\]):匹配RGB头部标签(6位非空白字符包裹在[]中)((?!\[\S{6}\]).)+?:负向预查,确保每一个字符之前都不是RGB头部标签的起始,+?非贪婪匹配直到遇到[-](\[\-\]):匹配尾部结束标签
这样就能确保匹配到的内容里不会包含其他头部标签,只提取合法的标签对包裹的内容。
内容的提问来源于stack exchange,提问作者kangbok
相关产品推荐
相关产品推荐

