
本教程旨在解决接收到多个json对象以非标准格式(即没有外部数组括号和逗号分隔)直接连接的场景。我们将介绍一种python解析策略,通过识别json对象的结束和开始标记来精确分割数据流,从而实现对每个独立json对象的成功解析和处理。
在处理API响应或日志数据时,我们通常期望接收到符合RFC 8259标准的JSON格式,例如单个JSON对象或一个包含多个JSON对象的数组。然而,在某些情况下,可能会遇到一种非标准的数据流,其中多个独立的JSON对象直接连接在一起,没有外部的方括号 [] 包裹,也没有逗号 , 进行分隔。这种格式使得标准的 json.loads() 函数无法直接解析整个字符串,因为它不是一个有效的JSON文档。
以下是一个典型的非标准JSON数据流示例:
{
"self": "https://example1.com",
"key": "keyOne",
"name": "nameOne",
"emailAddress": "mailOne",
"avatarUrls": { /* ... */ },
"displayName": "displayNameOne",
"active": true,
"timeZone": "Europe",
"locale": "en_UK"
}
{
"self": "https://example2.com",
"key": "keyTwo",
"name": "nameTwo",
"emailAddress": "mailTwo",
"avatarUrls": { /* ... */ },
"displayName": "displayNameTwo",
"active": false,
"timeZone": "Europe",
"locale": "en_US"
}在这种结构中,一个JSON对象的结束符 } 之后紧跟着下一个JSON对象的开始符 {,它们之间可能只有换行符。我们的目标是识别这些边界,并将数据流分割成独立的、可解析的JSON字符串。
由于每个JSON对象都是一个独立的实体,其结束标志是 },而下一个对象的开始标志是 {。我们可以利用这一特性,逐行扫描整个数据流。当检测到当前行是 { 并且前一行是 } 时,就意味着我们找到了两个JSON对象之间的边界。
立即学习“Python免费学习笔记(深入)”;
具体的解析步骤如下:
下面是使用Python实现上述解析策略的示例代码:
import json
# 示例非标准JSON数据流
data_stream = '''
{
"self": "https://example1.com",
"key": "keyOne",
"name": "nameOne",
"emailAddress": "mailOne",
"avatarUrls": {
"48x48": "https://test.com/secure/useravatar?avatarId=1",
"24x24": "https://test.com/secure/useravatar?size=small&avatarId=1",
"16x16": "https://test.com/secure/useravatar?size=xsmall&avatarId=1",
"32x32": "https://test.com/secure/useravatar?size=medium&avatarId=1"
},
"displayName": "displayNameOne",
"active": true,
"timeZone": "Europe",
"locale": "en_UK"
}
{
"self": "https://example2.com",
"key": "keyTwo",
"name": "nameTwo",
"emailAddress": "mailTwo",
"avatarUrls": {
"48x48": "https://test.com/secure/useravatar?avatarId=2",
"24x24": "https://test.com/secure/useravatar?size=small&avatarId=2",
"16x16": "https://test.com/secure/useravatar?size=xsmall&avatarId=2",
"32x32": "https://test.com/secure/useravatar?size=medium&avatarId=2"
},
"displayName": "displayNameTwo",
"active": false,
"timeZone": "Europe",
"locale": "en_US"
}
'''
def parse_concatenated_json(data_string: str) -> list:
"""
解析包含多个直接连接的非标准JSON对象的字符串。
Args:
data_string: 包含非标准JSON对象流的字符串。
Returns:
一个包含所有解析出的JSON字典的列表。
"""
json_objects = []
lines = data_string.strip().splitlines() # 移除首尾空白并按行分割
current_object_start_line = 0 # 记录当前JSON对象开始的行索引
for i, line in enumerate(lines):
# 检查当前行是否为"{"且前一行是否为"}"
# 并且确保不是第一个JSON对象的开始(i > 0)
if i > 0 and line.strip() == "{" and lines[i-1].strip() == "}":
# 找到一个JSON对象的边界,解析前一个对象
json_segment = "\n".join(lines[current_object_start_line:i])
try:
json_objects.append(json.loads(json_segment))
except json.JSONDecodeError as e:
print(f"解析JSON片段失败: {e}\n片段内容:\n{json_segment}")
# 根据实际需求选择是跳过、记录错误还是中断
pass
# 更新下一个JSON对象的起始行
current_object_start_line = i
# 处理最后一个JSON对象
if current_object_start_line < len(lines):
json_segment = "\n".join(lines[current_object_start_line:])
try:
json_objects.append(json.loads(json_segment))
except json.JSONDecodeError as e:
print(f"解析最后一个JSON片段失败: {e}\n片段内容:\n{json_segment}")
return json_objects
# 调用解析函数
parsed_data = parse_concatenated_json(data_stream)
# 打印解析结果以验证
print(f"成功解析 {len(parsed_data)} 个JSON对象:")
for obj in parsed_data:
print(json.dumps(obj, indent=2, ensure_ascii=False)) # 格式化输出,方便阅读代码解析:
通过上述基于行识别边界的策略,我们可以有效地解析和处理那些不符合标准JSON数组格式,而是以非标准方式直接连接的多个JSON对象流。这种方法为处理来自不规范数据源的JSON数据提供了一个实用的解决方案。
以上就是Python中解析非标准格式的多重JSON对象流的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号