[英]How to parse "{Key=Value}" structs into JSON with Python?
如果我在 AWS 中运行 Athena 查询,我返回的数据包含带有键/值对的结构,如下所示:
{
"events": "[{deviceType=Android,logins=400},{deviceType=iPhone,logins=550}]"
}
我可以使用正则表达式来解析它,但是特殊字符之类的东西使反序列化非常容易出错。
例如,如果我使用正则表达式, {deviceType=Android, date=2022-01-01}
将遇到分隔符问题。
是否有针对此类事物的现有反序列化器?
编辑:
这是我的反序列化正则表达式:
def deserialize(s):
# Surround any word with "
s1 = re.sub('(\w+)', '"\g<1>"', s)
# Replace = with :
s2 = re.sub('=', ':', s1)
return json.loads(s2)
当值中有特殊字符(如“-”或“.”)时,这会出现问题。 正则表达式无法正确确定“单词”,因此无法正确放置引号。
引号内的数据几乎是 JSON,但缺少键和值周围的引号。 通过一些明智的链接.replace()
方法调用,您应该能够将它从几乎 JSON 转换为 JSON,然后使用 json 模块反序列化它:
import json
obj = {"events": "[{deviceType=Android, date=2022-01-01}]"}
events = obj['events']
events_json = events.replace(', ', ',').replace('{', '{"').replace('}', '"}').replace('=', '":"').replace(',', '","').replace('}","{','},{')
parsed = json.loads(events_json)
print(parsed[0])
print(parsed[0]['deviceType']) # prints 'Android'
print(parsed[0]['date']) # prints '2022-01-01'
*编辑以修复 MisterMiyagi 提出的问题。
我建议在您的查询中将映射和 arrays 转换为 JSON,而不是解析这个不完全 JSON:
SELECT CAST(events AS JSON) AS events …
这具有使 output 更容易解析的额外好处(例如,如果不强制转换为 JSON,则无法知道“[1, 2, 3]” 是否为整数或字符串数组,或者如果“[hello, world ]" 是一个包含两个元素的数组,或者一个包含逗号的元素)。
给定如图所示的数据,您可以使用 RE 将大括号之间的字符串隔离开,然后将这些字符串进一步拆分为它们的组成部分。 这是一个例子:
import re
d = {'events': "[{deviceType=Android,logins=400},{deviceType=iPhone,logins=550}]"}
for t in re.findall('(?<={).+?(?=})', d['events']):
for p in t.split(','):
print(p)
Output:
deviceType=Android
logins=400
deviceType=iPhone
logins=550
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.