我有一个要作为字典加载的字符串,以便可以访问每个项目。
my_str = "[
id=xyz-111,
abc= {
item=[
{
a=xyz,
b=123,
c={},
d={
i=[{ip=0.0.0.0/0}]
},
}
]
}
]"
当前,我正在使用正则表达式(re库)来获取字符串中任何项目的值,这是可行的。
有没有更清洁的方法将此字符串转换为字典?我尝试过json.loads()
和ast
无效。
预期结果:
my_dict = {
'id':'xyz-111',
'abc': {
'item':[
{
'a':'xyz',
'b':123,
'c':{},
'd':{
'i':[{'ip':'0.0.0.0/0'}]
},
}
]
}
}
答案 0 :(得分:3)
嗯,这很丑陋,但它可能为您提供一个起点,从那里可以创建更有效的解决方案。基本上,第一个替换是一系列替换,包括切片和用dict封闭替换开合括号。然后,ast.literal_eval
转换为字典。
import ast
import re
s = """
[
id=xyz-111,
abc= {
item=[
{
a=xyz,
b=123,
c={},
d={
i=[{ip=0.0.0.0/0}]
},
}
]
}
]
"""
a = '{' + re.sub(r'=', r':', re.sub(r'\s+', '', s))[1:-1] + '}'
b = re.sub(r'([{}[\]:,])([^{}[\]:,])', r'\1"\2', a)
c = re.sub(r'([^{}[\]:,])([{}[\]:,])', r'\1"\2', b)
d = ast.literal_eval(c)
print(d)
# {'id': 'xyz-111', 'abc': {'item': [{'a': 'xyz', 'b': '123', 'c': {}, 'd': {'i': [{'ip': '0.0.0.0/0'}]}}]}}
a
删除所有空白,将=
替换为:
,并将外部[]
替换为{}
(空白删除是一种钝器,需要使用如果数据中包含需要保留空格的字符串,则可以更具体地定位目标b
将"
插入方括号,分号或逗号后,再不插入任何这些字符c
在括号,分号或逗号之前插入"
,这些字符中没有任何一个d
使用ast.literal_eval
将字符串转换为字典,比json.loads
宽容得多答案 1 :(得分:0)
我同意您的看法,通常json.loads()
是摄取该内容的首选。那个字符串是从哪里来的?
似乎某些代码的layer_1生成了格式正确的JSON, 然后layer_2删除引号。 找到layer_2,并告诉它停止这样做。 或者,复制layer_2, 有自己的代码使用原始输入 并更好地处理它, 这样报价就不会丢失。
肯定还有 那里还有一些结构,
在标点和行尾之间
因此在最坏的情况下,值得您花一点时间一起破解UnStrip
例行程序将丢失的引号放回去。
在例如b=123
,发出'b':'123'
并不坏,
您可以随时发布流程,
在其中递归地尝试将字典值转换为数字,
try
/ except
时忽略错误
看起来更像'xyz'
,而不是整数。
实际上,将n = float(s)
包装在try
中的示例是有启发性的。
在输入的任何给定行中可能会有一些歧义,
并可以选择将变体A或B用作有效JSON。
尝试将两者都包裹在try
中可能很有用,
然后返回第一个获胜的
第一个评估为有效JSON的人。