我有这个字符串我想加载为字典,以便我可以访问每个项目。
my_str = "[
id=xyz-111,
abc= {
item=[
{
a=xyz,
b=123,
c={},
d={
i=[{ip=0.0.0.0/0}]
},
}
]
}
]"
目前我正在使用正则表达式(re library)来获取字符串中任何项的值,这是有效的。
有没有更简洁的方法将此字符串转换为字典?我尝试过json.loads()
和ast
不起作用。
预期结果:
my_dict = {
'id':'xyz-111',
'abc': {
'item':[
{
'a':'xyz',
'b':123,
'c':{},
'd':{
'i':[{'ip':'0.0.0.0/0'}]
},
}
]
}
}
嗯,这非常难看,但它可能会为您提供一个创建更有效解决方案的起点。基本上,一系列替换,第一个包括切片和用dict闭合替换开口和闭合括号。然后,ast.literal_eval
转换为dict。
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
使用"
将字符串转换为dict,这比d
稍微宽容一些我同意你的观点,通常ast.literal_eval
将成为摄取它的首选。这个字符串来自哪里?
似乎某些代码的layer_1生成了格式良好的JSON,然后layer_2删除了引号。找到layer_2,告诉它停止这样做。或者,复制layer_2,让您自己的代码使用原始输入并更好地处理它,因此引号不会丢失。
当然,在标点符号和行结尾之间仍然存在一些结构,因此在最坏情况下,将UnStrip例程放回到缺失的引号中是值得的。例如,在例如json.loads
,发出json.loads()
并不是那么糟糕,因为你可以随时发布进程,你递归地尝试将字典值转换为数字,使用b=123
/ 'b':'123'
忽略错误,如果值看起来更像try
而不是一些整数。
实际上,在except
中包装'xyz'
的例子是有益的。在输入的任何给定行中可能存在一些歧义,可以选择将变量A或B作为有效的JSON。尝试两者,包装在n = float(s)
中,并返回第一个获胜,第一个评估为有效JSON的可能是有用的。