Python中如何用正则重复匹配解析Object格式字符串?
问题描述
需要解析格式固定的长字符串,示例字符串如下:
'''Object{identifier='d6e461c5-fd55-42cb-b3e8-40072670fd0f', name='some_name2', identifier='d6e461c5-fd55-42cb-b3e8-40072670fd0f', name='some_name3', value=value_without_quotes}'''
目标是提取所有键值对,整理为如下格式的列表:
["'identifier', ''d6e461c5-fd55-42cb-b3e8-40072670fd0f''", "'name', ''some_name2''", "'identifier', ''d6e461c5-fd55-42cb-b3e8-40072670fd0f''", "'name', ''some_name3''", "'value', 'value_without_quotes'"]
此前尝试的正则表达式(如r'Object{(+?)=(+?)}'、re.match(r'Object{((.+?)=(.+?),?)+}', line3).groups())无法正确匹配所有键值对:要么仅能匹配单个,要么返回错误的组合。且值可能包含引号、符号或数字,需要实现连续重复匹配。
解决方案
1. 核心正则思路
先剥离外层的Object{}结构,再匹配内部每一组key=value。针对值的两种类型(带单引号/不带引号)设计匹配规则:
- 带单引号的值:匹配从
'开始,到未被转义的'结束的内容(支持值内包含转义单引号,如'it\'s valid') - 不带引号的值:匹配到下一个逗号或右大括号为止
对应的正则表达式:
r'(\w+)=(\'[^\'\\]*(?:\\.[^\'\\]*)*\'|[^,}]+)'
各部分解释:
(\w+):匹配键名(字母、数字、下划线组成)=:匹配键值分隔符- 二选一匹配规则:
\'[^\'\\]*(?:\\.[^\'\\]*)*\':处理带单引号的值,兼容转义字符[^,}]+:处理不带引号的值,终止于逗号或右大括号
2. 完整代码实现
import re input_str = '''Object{identifier='d6e461c5-fd55-42cb-b3e8-40072670fd0f', name='some_name2', identifier='d6e461c5-fd55-42cb-b3e8-40072670fd0f', name='some_name3', value=value_without_quotes}''' # 提取Object{}内部的核心内容 inner_content = re.search(r'Object\{(.*)\}', input_str).group(1) # 匹配所有键值对 matches = re.findall(r'(\w+)=(\'[^\'\\]*(?:\\.[^\'\\]*)*\'|[^,}]+)', inner_content) # 整理为目标格式的列表 result = [f"'{key}', ''{value}''" if value.startswith("'") else f"'{key}', '{value}'" for key, value in matches] print(result)
运行后输出与目标一致:
["'identifier', ''d6e461c5-fd55-42cb-b3e8-40072670fd0f''", "'name', ''some_name2''", "'identifier', ''d6e461c5-fd55-42cb-b3e8-40072670fd0f''", "'name', ''some_name3''", "'value', 'value_without_quotes'"]
3. 此前正则失败的原因
r'Object{(+?)=(+?)}':存在语法错误(+?前无匹配内容),且仅能匹配单个键值对,无法处理多组数据。re.match(r'Object{((.+?)=(.+?),?)+}', line3).groups():重复捕获组只会保留最后一次匹配的结果,groups()无法返回所有键值对;改用findall可直接获取全部匹配项。
内容的提问来源于stack exchange,提问作者Daniel Smialkowsky
相关产品推荐
相关产品推荐

