Python regex分割键值对 忽略尖括号内逗号支持嵌套结构
实现忽略尖括号内逗号的顶层键值对分割
现有正则的核心问题是没有感知尖括号的嵌套层级,会把所有逗号都识别为顶层分隔符,以下两种方案都可以实现需求,拿到正确的顶层拆分结果后即可自行编写递归逻辑处理任意深度的嵌套结构。
方案1:基于平衡组正则实现
Python 标准库re模块不支持平衡组匹配,需要先安装第三方regex库(执行pip install regex即可安装),使用以下正则可以直接匹配所有顶层键值对,自动跳过尖括号包裹范围内的逗号:
([^:]+):((?:[^<>]|<(?P<d>)|>(?P<-d>))*(?(d)(?!))(?:,|$))
正则逻辑说明:
- 第一捕获组匹配键名,匹配到顶层冒号即停止,兼容带连字符的键名
- 值部分匹配时维护尖括号深度计数器:遇到左尖括号深度+1,遇到右尖括号深度-1
- 仅当深度为0时(即不在任何尖括号包裹范围内),才将逗号识别为键值对分隔符,同时兼容字符串末尾的最后一个键值对
使用示例:
import regex test_str = "document-name:string,document-type:string,description:string,initiative-name:string,milestone:struct<key:string,name:string,sub:struct<a:int,b:float>>,size:int" pat = regex.compile(r'([^:]+):((?:[^<>]|<(?P<d>)|>(?P<-d>))*(?(d)(?!))(?:,|$))') top_kv = {} for item in pat.finditer(test_str): key = item.group(1).strip() value = item.group(2).rstrip(',').strip() top_kv[key] = value
执行后top_kv输出结果如下,milestone字段对应的值完整保留了内部嵌套结构,不会被内部逗号截断:
{ 'document-name': 'string', 'document-type': 'string', 'description': 'string', 'initiative-name': 'string', 'milestone': 'struct<key:string,name:string,sub:struct<a:int,b:float>>', 'size': 'int' }
方案2:纯遍历实现(无第三方依赖)
如果不想安装第三方库,可以直接通过一次字符串遍历维护尖括号深度,仅在深度为0时识别分隔符,逻辑更直观,性能更优:
def split_top_level_kv(s: str) -> dict: result = {} bracket_depth = 0 seg_start = 0 colon_idx = -1 for idx, char in enumerate(s): if char == '<': bracket_depth += 1 elif char == '>': bracket_depth -= 1 elif char == ':' and bracket_depth == 0: colon_idx = idx elif char == ',' and bracket_depth == 0: key = s[seg_start:colon_idx].strip() val = s[colon_idx+1:idx].strip() result[key] = val seg_start = idx + 1 # 处理最后一个键值对 last_key = s[seg_start:colon_idx].strip() last_val = s[colon_idx+1:].strip() result[last_key] = last_val return result # 测试 test_str = "document-name:string,document-type:string,description:string,initiative-name:string,milestone:struct<key:string,name:string,sub:struct<a:int,b:float>>,size:int" print(split_top_level_kv(test_str))
运行结果和正则方案完全一致,支持任意深度的尖括号嵌套场景。
内容的提问来源于stack exchange,提问作者Raiden616
相关产品推荐
相关产品推荐

