如何解析非数组形式的多JSON对象脏数据?
解析串联式无效JSON的实用方法
这个问题我碰到过好几次,其实核心是要准确识别每个独立JSON对象的边界——毕竟直接按空格或换行拆分肯定不行,因为对象内部可能有嵌套括号、换行或者包含{/}的字符串。这里有几个靠谱的解决办法:
方法一:手动括号计数(通用无依赖)
这种方法不需要额外库,通过遍历字符串、跟踪括号数量和字符串状态(是否处于引号内)来拆分每个完整的JSON对象,逻辑清晰且兼容性强。
以Python为例:
import json def parse_concatenated_json(raw_str): parsed_objects = [] start_idx = 0 bracket_count = 0 in_quote = False is_escaped = False for idx, char in enumerate(raw_str): # 处理字符串内的转义字符 if char == "\\" and in_quote: is_escaped = not is_escaped continue # 切换引号状态(仅当未被转义时) if char == '"' and not is_escaped: in_quote = not in_quote # 仅在非字符串状态下跟踪括号 elif not in_quote: if char == "{": bracket_count += 1 elif char == "}": bracket_count -= 1 # 当括号回到0时,说明找到一个完整的JSON对象 if bracket_count == 0: obj_str = raw_str[start_idx:idx+1].strip() if obj_str: parsed_objects.append(json.loads(obj_str)) start_idx = idx + 1 # 重置转义标记(非转义字符后) is_escaped = False # 处理最后可能剩余的完整对象 remaining = raw_str[start_idx:].strip() if remaining and bracket_count == 0: parsed_objects.append(json.loads(remaining)) return parsed_objects # 测试你的输入 input_data = '{"output": "te\ns\nt"} {"output": "test"} ' result = parse_concatenated_json(input_data) print(json.dumps(result, indent=2))
运行后会输出有效的JSON数组:
[ { "output": "te\ns\nt" }, { "output": "test" } ]
方法二:用支持平衡组的正则表达式
如果你的语言支持平衡括号匹配的正则(比如Python的regex库,而非标准库的re),可以用正则直接提取所有完整的JSON对象,代码更简洁。
示例(Python):
import regex import json input_data = '{"output": "te\ns\nt"} {"output": "test"} ' # 正则模式:匹配平衡的{},忽略字符串内的括号 pattern = r'\{(?:[^{}]|(?R))*\}' # 提取所有匹配的JSON对象字符串 obj_strings = regex.findall(pattern, input_data) # 逐个解析为JSON对象并组成数组 result = [json.loads(s) for s in obj_strings] print(json.dumps(result, indent=2))
补充说明
- 这两种方法都能处理JSON对象内的换行、嵌套括号和转义字符,比简单的字符串拆分靠谱得多。
- 如果是在JavaScript环境中,思路类似:可以手动遍历计数括号,或者使用专门修复无效JSON的工具库来直接转换为数组。
内容的提问来源于stack exchange,提问作者Wouter Bloeyaert
相关产品推荐
相关产品推荐

