如何从含捕获组的正则表达式中提取未捕获的原始文本?
从正则表达式提取未捕获的原始文本片段
我们可以利用Python内置的sre_parse模块解析正则表达式结构,准确区分捕获组与其他正则元素,从而高效提取所有未被捕获的文本片段。以下是实现代码:
import sre_parse def extract(pattern): fragments = [] current_fragment = [] def elem_to_string(element): """将sre_parse解析出的元素转换为对应的正则字符串""" elem_type, value = element if elem_type == 'literal': return chr(value) elif elem_type == 'any': return '.' elif elem_type == 'range': start, end = value return f"[{chr(start)}-{chr(end)}]" elif elem_type == 'at': return '^' if value == 'bos' else '$' elif elem_type in ('max_repeat', 'min_repeat'): min_count, max_count, sub_elem = value sub_str = elem_to_string(sub_elem) if min_count == 0 and max_count == 1: return f"{sub_str}?" elif min_count == 0 and max_count == sre_parse.MAXREPEAT: return f"{sub_str}*" elif min_count == 1 and max_count == sre_parse.MAXREPEAT: return f"{sub_str}+" else: return f"{sub_str}{{{min_count},{max_count}}}" elif elem_type == 'subpattern': # 处理非捕获组 sub_content = ''.join(elem_to_string(e) for e in value[1]) return f"(?:{sub_content})" # 其他未覆盖的正则元素可根据需求扩展 return '' # 遍历解析后的正则元素 for elem in sre_parse.parse(pattern): if elem[0] == 'group': # 遇到捕获组,将当前累积的片段存入结果 fragments.append(''.join(current_fragment)) current_fragment = [] continue # 非捕获组元素,转换为字符串后累积 current_fragment.append(elem_to_string(elem)) # 添加最后一段(捕获组之后的内容,可能为空) fragments.append(''.join(current_fragment)) return fragments
测试验证
分别验证三个示例场景:
- 多捕获组场景
pattern = r"Date: (\d{4})-(\d{2})-(\d{2})" assert extract(pattern) == ["Date: ", "-", "-", ""]
- 单捕获组场景
pattern = r"hello (world)" assert extract(pattern) == ["hello ", ""]
- 含转义字符场景
pattern = r"\(born in (.*)\)" assert extract(pattern) == ["(born in ", ")"]
实现说明
- 借助
sre_parse模块直接解析正则表达式的语法结构,无需手动遍历字符串,高效且能正确处理转义字符。 - 通过
elem_to_string函数将解析后的元素转换为对应的正则字符串,覆盖了常见的正则语法(字面量、通配符、字符范围、重复限定符、非捕获组等)。 - 遇到捕获组时,立即将当前累积的非捕获片段存入结果,跳过捕获组内部内容,确保只提取未被捕获的部分。
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

