如何将采用2/4空格缩进的文本转换为JSON格式?
缩进文本转JSON的索引错误修复方案
问题背景
我已花费数小时尝试将空格缩进的文本转换为JSON格式。原始文本中,嵌套值采用4空格缩进,键值对采用2空格缩进。编写的Python代码运行时出现索引错误,以下是相关代码、原始数据及期望结果:
尝试代码
import json from pprint import pprint lines = raw_text.strip().split('\n') result = {} stack = [(0, result)] for line in lines: indent, content = line.split(':', 1) indent_level = len(indent) - len(indent.lstrip()) key = content.strip() value = None if key == "null" else {} print(indent_level, stack[-1][0]) while indent_level <= stack[-1][0]: stack.pop() parent = stack[-1][1] # 此处出现索引错误 parent[key] = value stack.append((indent_level, value)) j = json.dumps(result, indent=4)
原始数据
text = r""" h0: h1: de8 h1b: null h1c: h2: h3: A h3a: S h3b: h4: h5: 81 h1b: h1bi: null h1bii: null """
期望JSON结果
{ "h0": { "h1a": "de8", "h1b": "null", "h1c": { "h2a": { "h3a": "A", "h3b": "S", "h3c": { "h4a": { "h5a": "81" } } } }, "h1d": { "h1di": "null", "h1dii": { "h2di": "hello", "h2dii": "hi" } } } }
错误原因及修复
核心问题
- 索引错误触发点:
while indent_level <= stack[-1][0]: stack.pop()会将栈中所有层级大于等于当前缩进的元素弹出,处理最顶层元素时可能把栈弹空,导致stack[-1]报错。 - 缩进层级计算逻辑错误:代码直接用空格数作为层级,未按原始文本规则(2空格=1层级单位)换算,导致层级判断混乱。
- 键值处理逻辑缺失:遇到具体文本值(如
de8)时错误设为{};原始文本重复键(h1b)会被直接覆盖。 - 变量名不匹配:代码使用
raw_text但原始数据变量是text,存在引用错误。
修复后的代码
import json # 统一输入变量名 raw_text = r""" h0: h1: de8 h1b: null h1c: h2: h3: A h3a: S h3b: h4: h5: 81 h1b: h1bi: null h1bii: null """ lines = raw_text.strip().split('\n') result = {} # 初始化栈,存储(层级, 对应字典) stack = [(0, result)] for line in lines: if ':' not in line: continue indent_part, content = line.split(':', 1) # 按2空格为1层级转换缩进数 indent_spaces = len(indent_part) - len(indent_part.lstrip()) indent_level = indent_spaces // 2 key = content.strip() # 区分值类型:null/空内容/具体文本 if key == "null": value = None elif not key: value = {} else: value = key # 仅弹出层级高于当前的栈元素,保留父节点 while stack[-1][0] > indent_level: stack.pop() parent = stack[-1][1] # 处理重复键,添加数字后缀避免覆盖 if key in parent: suffix = 1 while f"{key}{suffix}" in parent: suffix += 1 key = f"{key}{suffix}" parent[key] = value # 仅字典类型入栈,用于后续嵌套 if isinstance(value, dict): stack.append((indent_level + 1, value)) # 生成格式化JSON j = json.dumps(result, indent=4) print(j)
修复说明
- 缩进标准化:将缩进空格数除以2,统一为层级单位,匹配原始文本2空格键值对、4空格嵌套的规则。
- 栈逻辑修正:调整弹出条件为
stack[-1][0] > indent_level,避免弹空栈,同时保证父节点正确。 - 值处理完善:区分空内容(生成字典)、
null(生成None)、具体文本值(生成字符串)三种情况。 - 重复键处理:为重复键添加数字后缀,保留所有原始数据。
- 变量名统一:修正输入变量名不一致的问题,保证代码可直接运行。
内容的提问来源于stack exchange,提问作者dallascow
相关产品推荐
相关产品推荐

