解析 Json 中不带引号的 Python
Parse Json without quotes in Python
我正在尝试将 JSON 输入解析为 Python 中的字符串,无法将其解析为列表或字典,因为 JSON 输入的格式不正确(由于中间件的限制在这里不能做太多。)
{
"Records": "{Output=[{_fields=[{Entity=ABC , No=12345, LineNo= 1, EffDate=20200630}, {Entity=ABC , No=567, LineNo= 1, EffDate=20200630}]}"
}
我尝试了 json.loads
和 ast.literal
(无效语法错误)。
如何加载这个?
令人遗憾的答案是:您的 "Records"
字段的内容 根本不是 JSON。再多的临时补丁(=
到 :
,添加引号)也不会改变这一点。您必须找出生产系统发出的内容的 language/format 规范和 write/find 适合该特定格式的解析器 .
作为离合器,并且只有在上面的示例已经捕获了您可能在生产数据中看到的所有可变性的情况下,一种基于正则表达式的更简单的方法(参见程序包 re
或 edd 的实用答案) 可能就足够了。
据我所知,您正在尝试将字典中 Records
项的值解析为 JSON,很遗憾,您不能。
那个值里的字符串不是JSON,你必须自己写一个解析器,先把这个字符串按照自己写的格式解析成JSON字符串. (不幸的是,我们不知道您在说什么“中间件”)。
tldr:将其解析为 JSON 字符串,然后将 JSON 解析为 python 字典。阅读 this 以了解有关 JSON(Javascript 对象表示法)规则的更多信息。
如果数据的生产者是一致的,您可以从类似下面的内容开始,旨在弥合 JSON 差距。
import re
import json
source = {
"Records": "{Output=[{_fields=[{Entity=ABC , No=12345, LineNo= 1, EffDate=20200630}, {Entity=ABC , No=567, LineNo= 1, EffDate=20200630}]}"
}
s = source["Records"]
# We'll start by removing any extraneous white spaces
s2 = re.sub('\s', '', s)
# Surrounding any word with "
s3 = re.sub('(\w+)', '"\g<1>"', s2)
# Replacing = with :
s4 = re.sub('=', ':', s3)
# Lastly, fixing missing closing ], }
## Note that }} is an escaped } for f-string.
s5 = f"{s4}]}}"
>>> json.loads(s5)
{'Output': [{'_fields': [{'Entity': 'ABC', 'No': '12345', 'LineNo': '1', 'EffDate': '20200630'}, {'Entity': 'ABC', 'No': '567', 'LineNo': '1', 'EffDate': '20200630'}]}]}
跟进一些稳健的测试,并使用您最喜欢的工具制作精美的 ETL。
给你。此代码将使它有效 json:
notjson = """{
"Records": "{Output=[{_fields=[{Entity=ABC , No=12345, LineNo= 1, EffDate=20200630}, {Entity=ABC , No=567, LineNo= 1, EffDate=20200630}]}"
}"""
notjson = notjson.replace("=","':") #adds a singlequote and makes it more valid
notjson = notjson.replace("{","{'")
notjson = notjson.replace(", ",", '")
notjson = notjson.replace("}, '{","}, {")
json = "{" + notjson[2:]
print(json)
print(notjson)
我正在尝试将 JSON 输入解析为 Python 中的字符串,无法将其解析为列表或字典,因为 JSON 输入的格式不正确(由于中间件的限制在这里不能做太多。)
{
"Records": "{Output=[{_fields=[{Entity=ABC , No=12345, LineNo= 1, EffDate=20200630}, {Entity=ABC , No=567, LineNo= 1, EffDate=20200630}]}"
}
我尝试了 json.loads
和 ast.literal
(无效语法错误)。
如何加载这个?
令人遗憾的答案是:您的 "Records"
字段的内容 根本不是 JSON。再多的临时补丁(=
到 :
,添加引号)也不会改变这一点。您必须找出生产系统发出的内容的 language/format 规范和 write/find 适合该特定格式的解析器 .
作为离合器,并且只有在上面的示例已经捕获了您可能在生产数据中看到的所有可变性的情况下,一种基于正则表达式的更简单的方法(参见程序包 re
或 edd 的实用答案) 可能就足够了。
据我所知,您正在尝试将字典中 Records
项的值解析为 JSON,很遗憾,您不能。
那个值里的字符串不是JSON,你必须自己写一个解析器,先把这个字符串按照自己写的格式解析成JSON字符串. (不幸的是,我们不知道您在说什么“中间件”)。
tldr:将其解析为 JSON 字符串,然后将 JSON 解析为 python 字典。阅读 this 以了解有关 JSON(Javascript 对象表示法)规则的更多信息。
如果数据的生产者是一致的,您可以从类似下面的内容开始,旨在弥合 JSON 差距。
import re
import json
source = {
"Records": "{Output=[{_fields=[{Entity=ABC , No=12345, LineNo= 1, EffDate=20200630}, {Entity=ABC , No=567, LineNo= 1, EffDate=20200630}]}"
}
s = source["Records"]
# We'll start by removing any extraneous white spaces
s2 = re.sub('\s', '', s)
# Surrounding any word with "
s3 = re.sub('(\w+)', '"\g<1>"', s2)
# Replacing = with :
s4 = re.sub('=', ':', s3)
# Lastly, fixing missing closing ], }
## Note that }} is an escaped } for f-string.
s5 = f"{s4}]}}"
>>> json.loads(s5)
{'Output': [{'_fields': [{'Entity': 'ABC', 'No': '12345', 'LineNo': '1', 'EffDate': '20200630'}, {'Entity': 'ABC', 'No': '567', 'LineNo': '1', 'EffDate': '20200630'}]}]}
跟进一些稳健的测试,并使用您最喜欢的工具制作精美的 ETL。
给你。此代码将使它有效 json:
notjson = """{
"Records": "{Output=[{_fields=[{Entity=ABC , No=12345, LineNo= 1, EffDate=20200630}, {Entity=ABC , No=567, LineNo= 1, EffDate=20200630}]}"
}"""
notjson = notjson.replace("=","':") #adds a singlequote and makes it more valid
notjson = notjson.replace("{","{'")
notjson = notjson.replace(", ",", '")
notjson = notjson.replace("}, '{","}, {")
json = "{" + notjson[2:]
print(json)
print(notjson)