我有一个看起来与JSON非常相似的数据结构:
"items"
{
"first"
{
"a" "1"
"b" "2"
"c" "3"
"d" "4"
"e" "5"
}
"second"
{
"f" "6"
"g" "7"
"h" "8"
"i" "9"
"j" "10"
}
}
但是问题是这种格式不适用于JSON解析器。 Python中是否有任何方法可以将这种格式转换为JSON格式来管理我的数据?我尝试使用json.loads(json.dumps(data))
,但是它不起作用。当使用jsonObj['items']
来搜索这种格式的数据时,它将显示TypeError: string indices must be integers
。
我的目标是按照以下原则进行操作:
"items" :
{
"first" :
{
"a" : "1",
"b" : "2",
"c" : "3",
"d" : "4",
"e" : "5"
},
"second" :
{
"f" : "6",
"g" : "7",
"h" : "8",
"i" : "9",
"j" : "10"
}
}
答案 0 :(得分:1)
幸运的是,the format使用的原子与Python足够相似,我们可以将tokenize
和ast
模块用于即席解析器。
输入断开时,它可能会严重损坏,但适用于您的示例数据:)
import tokenize
import token
import ast
import io
import json
def parse_valve_format(data):
dest = {}
stack = [dest]
for tok in tokenize.tokenize(io.BytesIO(data.encode()).readline):
if tok.type == token.STRING:
ts = ast.literal_eval(tok.string)
if isinstance(stack[-1], str):
# already a string on the stack?
# this has to be a key-value setting
key = stack.pop(-1)
stack[-1][key] = ts
else:
# otherwise assume we'll find a } soon
stack.append(ts)
elif tok.type == token.OP and tok.string == "{":
obj = {}
key = stack.pop(-1)
stack[-1][key] = obj
stack.append(obj)
elif tok.type == token.OP and tok.string == "}":
assert isinstance(stack[-1], dict), "stray }"
stack.pop(-1)
return dest
result_dict = parse_valve_format(
"""
"items"
{
"first"
{
"a" "1"
"b" "2"
"c" "3"
"d" "4"
"e" "5"
}
"second"
{
"f" "6"
"g" "7"
"h" "8"
"i" "9"
"j" "10"
}
}
"""
)
print(json.dumps(result_dict, indent=2))
输出:
{
"items": {
"first": {
"a": "1",
"b": "2",
"c": "3",
"d": "4",
"e": "5"
},
"second": {
"f": "6",
"g": "7",
"h": "8",
"i": "9",
"j": "10"
}
}
}
答案 1 :(得分:0)
这不是JSON数据。
JSON数据的格式
{
"foo" : "bar"
"sample2": {
"key1: value
}
}
您的数据不是以这种方式存储的,至少不是以JSON格式存储的,因此JSON Parse函数将不起作用。
现在进入JSON分析器,它有时可以针对缺少的键或值进行更正,但是在您的情况下,它看起来好像不了解发生了什么。
您最好的选择是使用Regex Magic一点点将其转换为JSON格式并从那里开始。
答案 2 :(得分:0)
您可以滚动自己的解析器/编译器。这是一个仅适用于您给出的示例的示例。 (例如,不适用于包含空格或列表/数字/等的令牌。)
def match_str(s):
return len(s) >= 2 and s[0] == '"' and s[-1] == '"'
def match_terminal(s):
return s == "{" or s == "}"
def notjsonstr_to_jsonstr(s):
tokens = s.split()
xs = []
was_terminal = True
was_str = False
for token in tokens:
if len(xs) != 0 and xs[-1] == "}" and token != "}":
xs.append(",")
if match_terminal(token):
if was_str:
xs.append(":")
xs.append(token)
was_terminal = True
was_str = False
continue
if match_str(token):
if was_str:
xs.append(":")
elif not was_terminal:
xs.append(",")
xs.append(token)
was_str = not was_str
else:
raise Exception("Unexpected token")
was_terminal = False
return "".join(xs)
这当然是非常有缺陷的,只能在非常有限的语法下使用,并且可能会使任何解析器编写者皱鼻子。