You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解析含自定义分隔符的嵌套字符串中的层级数据

解决方案建议

针对你处理的这种嵌套结构化字符串,下面分别分析你提到的两种方案,并给出具体实现思路:

方案1:正则表达式(适合结构完全固定的场景)

因为你的字符串结构高度规整,可以先匹配出每个完整的组(包含组内所有条目和对应的组数值),再在每个组内提取条目信息。

实现步骤:

  1. 先匹配每个顶级组,正则模式(开启单行模式re.DOTALL):

    group_pattern = re.compile(r'\{\{\{(.*?)\};(\d+\.?\d*)\}\}', re.DOTALL)
    

    这个模式会捕获两个部分:组内的所有条目内容(捕获组1),以及组对应的数值(捕获组2)。

  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:状态式解析(鲁棒性更强)

通过跟踪括号层级,判断当前处于「组外层」「条目层」「组数值层」等状态,逐个字符或片段解析,适合格式可能有变动的场景。

实现思路:

  1. 用计数器跟踪当前的大括号层级,初始为0。
  2. 遍历字符串,遇到{则层级+1,遇到}则层级-1。
  3. 当层级为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 08:01:30