【问题标题】:Converting str to dict in python在python中将字符串转换为dict
【发布时间】:2014-06-03 07:14:48
【问题描述】:

我使用 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(),但没有运气。 有人可以帮助我朝着正确的方向前进吗? 提前致谢。

【问题讨论】:

  • 如果您无法获得生成严格 JSON 的流程,请尝试more relaxed parser
  • 这确实不是有效的 JSON;关键名称需要引用。 JSON 格式是否总是包含这么多空格?
  • @MartijnPieters :是的,键名确实应该用引号引起来。我也不确定空格的数量。
  • @Shark:我们可以尝试修复 JSON,或者您必须使用 demjson 来加载它。
  • @salmanwahed:问题在于以一种不会进一步破坏 JSON 格式的自动化方式。

标签: python json dictionary rrdtool


【解决方案1】:

确实,旧版本的 rddtool 导出 ECMA 脚本,而不是 JSON。根据this debian bug report,升级 1.4.8 应该会给你正确的 JSON。另见项目CHANGELOG

xport 的 JSON 输出现在实际上是 json 兼容的键 现在被正确引用了。

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

后者可以通过外部demjson library来完成:

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

【讨论】:

  • 使用demjson 比使用yaml 有什么优势吗? Bcz 都给了我正确的结果。
  • @Shark:YAML 声称是 JSON 的超集,这种语法恰好也适用于 YAML。 demjson 明确允许此处使用的语法,因为它认为这是 ECMAScript。可能有 some 语法,RDDTool 产生的任何一个工具都无法解析,但我的直觉是在这里使用 demjson。
  • @Shark 一个可能的优势是您的输出明确声称是 JSON。它只是 碰巧 是有效的 YAML,因此宽松的 JSON 解析器可能不太可能在以后的某个时候被它绊倒。
【解决方案2】:

这确实不是有效的 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]
    ]
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-25
    • 2011-05-30
    • 2018-07-27
    • 1970-01-01
    • 2019-03-27
    相关资源
    最近更新 更多