在python中将str转换为dict

dot*_*ash 3 python json dictionary rrdtool

我使用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  ]
  ]
}
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*ers 5

确实,旧版本的rddtool导出ECMA脚本,而不是JSON.根据这个debian bug报告,升级1.4.8应该给你正确的JSON.另见项目CHANGELOG:

现在,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]]}
Run Code Online (Sandbox Code Playgroud)

修复可以使用正则表达式完成; 我将假设所有标识符都在新行上或直接在开头{大括号之后.列表中的单引号必须更改为双引号; 只有在值中没有嵌入的单引号时,这才有效:

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)
Run Code Online (Sandbox Code Playgroud)

  • @Shark:YAML声称是JSON的超集,这种语法恰好也适用于YAML.demjson明确允许这里使用的语法,因为它将此视为ECMAScript.它可能是RDDTool生成的*some*语法,任何一个工具都不解析,但我的直觉就是在这里使用demjson. (2认同)
  • @Shark一个可能的优点是你的输出明确声称是JSON.它只发生*才是有效的YAML,所以一个宽松的JSON解析器可能不太可能在未来的某个时刻被它绊倒. (2认同)