小编典典

在Python中将str转换为dict

json

我是使用subprocess.Popen()从进程的输出中获得的:

    { about: 'RRDtool xport JSON output',
  meta: {
    start: 1401778440,
    step: 60,
    end: 1401778440,
    legend: [
      'rta_MIN',
      'rta_MAX',
      'rta_AVERAGE'
          ]
     },
  data: [
    [ null, null, null ],
    [ null, null, null ],
    [ null, null, null ],
    [ null, null, null ],
    [ null, null, null ],
    [ null, null, null  ]
  ]
}

对我来说,它似乎不是有效的json。我已经使用ast.literal_eval()json.loads(),但是没有运气。有人可以在正确的方向帮助我吗?提前致谢。


阅读 479

收藏
2020-07-27

共1个答案

小编典典

确实,rddtool导出ECMA脚本而不是JSON的旧版本。根据此debian错误报告,升级1.4.8应该会给您适当的JSON。另请参阅项目CHANGELOG

现在,通过正确引用xport的键,xport的JSON输出实际上实际上是json编译的。

如果您无法升级,则这里有两个选择。要么尝试重新格式化以应用引用的对象密钥标识符,要么使用更宽松的解析器并解析ECMA脚本对象表示法。

后者可以通过外部demjson库完成

>>> import demjson
>>> demjson.decode('''\
... { about: 'RRDtool xport JSON output',
...   meta: {
...     start: 1401778440,
...     step: 60,
...     end: 1401778440,
...     legend: [
...       'rta_MIN',
...       'rta_MAX',
...       'rta_AVERAGE'
...           ]
...      },
...   data: [
...     [ null, null, null ],
...     [ null, null, null ],
...     [ null, null, null ],
...     [ null, null, null ],
...     [ null, null, null ],
...     [ null, null, null  ]
...   ]
... }''')
{u'about': u'RRDtool xport JSON output', u'meta': {u'start': 1401778440, u'step': 60, u'end': 1401778440, u'legend': [u'rta_MIN', u'rta_MAX', u'rta_AVERAGE']}, u'data': [[None, None, None], [None, None, None], [None, None, None], [None, None, None], [None, None, None], [None, None, None]]}

可以使用正则表达式进行修复;我将假定所有标识符都在新行上或紧接在{花括号后。列表中的单引号必须更改为双引号。只有在值中也没有嵌入单引号的情况下,这才起作用:

import re
import json

yourtext = re.sub(r'(?:^|(?<={))\s*(\w+)(?=:)', r' "\1"', yourtext, flags=re.M)
yourtext = re.sub(r"'", r'"', yourtext)
data = json.loads(yourtext)
2020-07-27