如何解析含自定义分隔符的嵌套字符串中的层级数据
解决方案建议
针对你处理的这种嵌套结构化字符串,下面分别分析你提到的两种方案,并给出具体实现思路:
方案1:正则表达式(适合结构完全固定的场景)
因为你的字符串结构高度规整,可以先匹配出每个完整的组(包含组内所有条目和对应的组数值),再在每个组内提取条目信息。
实现步骤:
先匹配每个顶级组,正则模式(开启单行模式
re.DOTALL):group_pattern = re.compile(r'\{\{\{(.*?)\};(\d+\.?\d*)\}\}', re.DOTALL)这个模式会捕获两个部分:组内的所有条目内容(捕获组1),以及组对应的数值(捕获组2)。
对每个组的条目内容,再匹配单个条目,正则模式:
item_pattern = re.compile(r'\{(\[item\d+\]);(\d+\.?\d*);(\d+\.?\d*);(\d+\.?\d*)\}')捕获组1是item标识,2-4是需要的三个数值。
示例代码:
import re raw_str = "{{{{[item1];30;42;100}};70};{{{[item2];1;1;30.627};{[item3];1;1;22.8201};{[item4];1;1;46.5529}};33.529};{{{[item5];1;1;29.1262};{[item6];1;1;14.5631};{[item7];1;1;9.7087};{[item8];1;1;5.8252};{[item9];1;1;29.1262};{[item10];1;1;11.6506}};6.6988}}" # 匹配所有组 groups = group_pattern.findall(raw_str) result = [] for items_content, group_value in groups: # 匹配当前组内的所有条目 items = item_pattern.findall(items_content) for item_id, num1, num2, num3 in items: result.append({ 'item': item_id, 'group_value': group_value, 'values': (float(num1), float(num2), float(num3)) }) # 输出结果 for entry in result: print(entry)
优缺点:代码简洁,实现快;但对格式变动容忍度低,比如如果字符串出现多余空格、换行位置变化,可能需要调整正则。
方案2:状态式解析(鲁棒性更强)
通过跟踪括号层级,判断当前处于「组外层」「条目层」「组数值层」等状态,逐个字符或片段解析,适合格式可能有变动的场景。
实现思路:
- 用计数器跟踪当前的大括号层级,初始为0。
- 遍历字符串,遇到
{则层级+1,遇到}则层级-1。 - 当层级为3时,说明进入了条目所在的层级,开始收集条目内容;当层级从2降到1时,说明遇到了组的数值,记录该数值并关联之前收集的条目。
示例代码:
raw_str = "{{{{[item1];30;42;100}};70};{{{[item2];1;1;30.627};{[item3];1;1;22.8201};{[item4];1;1;46.5529}};33.529};{{{[item5];1;1;29.1262};{[item6];1;1;14.5631};{[item7];1;1;9.7087};{[item8];1;1;5.8252};{[item9];1;1;29.1262};{[item10];1;1;11.6506}};6.6988}}" brace_level = 0 current_group_items = [] current_token = '' group_value = None result = [] for char in raw_str: if char == '{': brace_level += 1 # 进入条目层级(层级3),如果当前有未处理的token,先清空 if brace_level == 3 and current_token: current_token = '' elif char == '}': brace_level -= 1 # 从条目层级退出(层级从3到2),解析当前条目 if brace_level == 2 and current_token: parts = current_token.split(';') if len(parts) == 4: item_id, num1, num2, num3 = parts current_group_items.append({ 'item': item_id, 'values': (float(num1), float(num2), float(num3)) }) current_token = '' # 从组数值层级退出(层级从1到0),关联组数值和条目 elif brace_level == 0 and group_value is not None: for item in current_group_items: item['group_value'] = group_value result.append(item) current_group_items = [] group_value = None elif char == ';': # 遇到分号,判断当前层级:如果是层级2,说明是组数值的分隔符 if brace_level == 2 and current_token: group_value = float(current_token.strip()) current_token = '' # 其他层级继续收集token else: current_token += char else: current_token += char # 输出结果 for entry in result: print(entry)
优缺点:对格式变动(比如空格、换行)兼容性更好,逻辑清晰;代码量比正则多,但更容易扩展和调试。
方案选择建议
- 如果你的字符串格式完全固定,不会有额外空格、换行或结构变动,优先用正则表达式,实现高效快捷。
- 如果需要处理格式可能变化的场景,或者未来可能扩展结构,优先用状态式解析,鲁棒性更强。
内容的提问来源于stack exchange,提问作者Shade
相关产品推荐
相关产品推荐

