我有一个非常大的类似JSON的文件,但它没有使用正确的JSON语法:没有引用对象键。我想编写一个脚本来修复文件,以便我可以使用json.loads
加载它。
我需要匹配后跟冒号的所有单词,并用引用的单词替换它们。我认为正则表达式是\w+\s*:
,我应该使用re.sub
,但我不确定该怎么做。
如何获取以下输入并获得给定的输出?
# In
{abc : "xyz", cde : {}, fgh : ["hfz"]}
# Out
{"abc" : "xyz", "cde" : {}, "fgh" : ["hfz"]}
# In
{
a: "b",
b: {
c: "d",
d: []
},
e: "f"
}
# Out
{
"a": "b",
"b": {
"c": "d",
"d": []
},
"e": "f"
}
答案 0 :(得分:9)
您可以利用以下事实:您的日志文件不是有效的JSON,而 有效YAML,而不是可能非常脆弱的正则表达式解决方案。使用PyYAML库,您可以将其加载到Python数据结构中,然后将其作为有效的JSON写回:
import json
import yaml
with open("original.log") as f:
data = yaml.load(f)
with open("jsonified.log", "w") as f:
json.dump(data, f)
答案 1 :(得分:2)
我建议将未包含在双引号中的整个单词匹配,并在它们周围添加引号:
import re
p = re.compile(r'(?<!")\b\w+\b(?!")')
test_str = "{abc : \"xyz\", cde : {}, fgh : [\"hfz\"]}"
print re.sub(p, r'"\g<0>"', test_str)
请参阅IDEONE demo,输出:
{"abc" : "xyz", "cde" : {}, "fgh" : ["hfz"]}
答案 2 :(得分:0)
我在寻找将邋J的JSON速记解析为python的方法时遇到了这个老问题。
我的输入如下:
'{lat: 8.5, lon: -80.0}'
而且,正如所说的那样,它必须是宽松的空间,它也可以是:
'{lat:8.5,lon:-80.0}'
我喜欢YAML提示,但是它与间距不合适并不顺利,我不希望在我已经很长的列表中添加一个依赖项,所以我尝试了正则表达式解决方案,但这还不够好对于我的情况。
我的解决方案如下:
re.sub(r'(\w+)[ ]*(?=:)', r'"\g<1>"', input_string)
它定义了一个组,包含字母数字数据,它允许跟随空格,它锚定到分号,它用第一组替换匹配的子字符串,用双引号括起来。所有其余的都是独自留下的。如果已经引用了密钥,则该模式将不匹配。
特别是:
>>> re.sub(r'(\w+)[ ]*(?=:)', r'"\g<1>"',
... '{abc : "xyz", cde : {a:"b", c: 0}, fgh : ["hfz"], 123: 123}')
'{"abc": "xyz", "cde": {"a":"b", "c": 0}, "fgh": ["hfz"], "123": 123}'
>>> re.sub(r'(\w+)[ ]*(?=:)', r'"\g<1>"', _)
'{"abc": "xyz", "cde": {"a":"b", "c": 0}, "fgh": ["hfz"], "123": 123}'
>>>