在python中将str转换为dict

时间:2014-06-03 07:14:48

标签: 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  ]
  ]
}

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

2 个答案:

答案 0 :(得分:5)

确实,rddtool的旧版本导出ECMA脚本,而不是JSON。根据{{​​3}}升级1.4.8应该给你正确的JSON。另请参阅项目this debian bug report

  

xport的JSON输出现在实际上是json由其键进行编译     正在被引用。

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

后者可以使用外部CHANGELOG

完成
>>> 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)

答案 1 :(得分:4)

这确实是无效的JSON。但是,它有效YAML,因此第三方PyYAML库可能会帮助您:

>>> import yaml
>>> yaml.load(text)
{
    'about': 'RRDtool xport JSON output',
    'meta': {
        'start': 1401778440,
        'step': 60,
        'end': 1401778440,
        'legend': [
            'rta_MIN',
            'rta_MAX',
            'rta_AVERAGE'
        ]
    },
    'data': [
        [None, None, None],
        [None, None, None],
        [None, None, None],
        [None, None, None],
        [None, None, None],
        [None, None, None]
    ]
}