Python 在类似JSON的文件中修复无引号的键,以便使用正确的JSON语法

Python 在类似JSON的文件中修复无引号的键,以便使用正确的JSON语法,python,regex,json,Python,Regex,Json,我有一个非常大的类似JSON的文件,但它没有使用正确的JSON语法:对象键没有被引用。我想写一个脚本来修复这个文件,这样我就可以用json.loads加载它 我需要匹配后面跟冒号的所有单词,并将它们替换为引用的单词。我认为正则表达式是\w+\s*:,我应该使用re.sub,但我不确定该怎么做 如何获取以下输入并获得给定的输出 # In {abc : "xyz", cde : {}, fgh : ["hfz"]} # Out {"abc" : "xyz", "cde" : {}, "fgh" :

我有一个非常大的类似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"
}

我建议将未包含在双引号中的整词进行匹配,并在其周围添加引号:

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)

您可以利用这样一个事实,即虽然日志文件不是有效的JSON,但它是有效的,而不是一个可能脆弱的正则表达式解决方案。使用该库,您可以将其加载到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)

我在寻找将草率的JSON速记解析为python的方法时遇到了这个老问题

我的输入如下所示:

'{lat: 8.5, lon: -80.0}'
re.sub(r'(\w+)[ ]*(?=:)', r'"\g<1>"', input_string)
而且,正如前面所说,它必须是松散的空间,它也可以是:

'{lat:8.5,lon:-80.0}'
我喜欢YAML提示,但它不适合草率的间距,我不希望在已经很长的列表中再添加一个依赖项,所以我尝试了正则表达式解决方案,但它对我的情况来说不够好

我的解决方案如下所示:

'{lat: 8.5, lon: -80.0}'
re.sub(r'(\w+)[ ]*(?=:)', r'"\g<1>"', input_string)
re.sub(r'(\w+)[]*(?=:)',r'\g',输入字符串)
它定义了一个组,包含字母数字数据,它允许后面有空格,它锚定到分号,它用组1替换匹配的子字符串,并用双引号括起来。剩下的就剩下了。如果该键已被引用,则此模式将不匹配

特别是:

>>> 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}'
>>> 
>>re.sub(r'(\w+)[]*(?=:)',r'\g',
…{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',”
“{”abc:“xyz”,“cde:{”a:“b”,“c”:0},“fgh:[“hfz”],“123”:123}”
>>> 

它是对整个匹配文本的明确反向引用。用于避免在整个模式中使用捕获组的开销。这正是我最初的问题想要了解的。如何在正则表达式中反向引用的概念。@akshitBhatia如果你想学习正则表达式反向引用,为什么不问这个问题?是的。这是为这个用例量身定做的答案。既然主持人已经编辑了我的原始问题,我应该选择正确的答案。但这是我想在我最初的问题中回答的一般概念,这个问题因过于宽泛而被搁置。我对你的答案投了赞成票,但选择了另一个,因为这是对已编辑问题的正确答案。@mariotomo请看上面的评论。它并不是要以目前的形式回答这个问题,而是经过了大量编辑。此外,我现在也不会回答这个问题,这篇文章已经3年了。我无意中发现了这条线索,为R中出现的相同问题寻找解决方案。这个解决方案与那里的包一样有效。谢谢感谢您提供了这个出色的解决方案!根据我遇到的文档和文章,我想指出使用yaml.safe_load()是阅读yaml的更安全的方法。见: