【问题标题】:Converting a Ruby hash string to a Python dictionary将 Ruby 哈希字符串转换为 Python 字典
【发布时间】:2013-10-11 13:30:02
【问题描述】:

我正在处理一些作为 Ruby 哈希字符串返回的命令输出。 (来自一个叫做 mcollective 的东西)。

这是我收到的示例字符串:

{:changes=>{"total"=>0},     :events=>{"failure"=>0, "success"=>0, "total"=>0},     :version=>      {"puppet"=>"2.7.21 (Puppet Enterprise 2.8.1)", "config"=>1381497648},     :time=>      {"filebucket"=>0.000287,       "cron"=>0.00212,       "package"=>0.398982,       "exec"=>0.001314,       "config_retrieval"=>5.60761618614197,       "anchor"=>0.001157,       "service"=>0.774906,       "total"=>9.85111718614197,       "host"=>0.002662,       "user"=>0.063606,       "file"=>2.998467,       "last_run"=>1381497660},     :resources=>      {"skipped"=>6,       "failed_to_restart"=>0,       "out_of_sync"=>0,       "failed"=>0,       "total"=>112,       "restarted"=>0,       "scheduled"=>0,       "changed"=>0}}

我有能力为此编写一个迷你解析器,但这将是一项繁琐的任务。有谁知道可以为我将其转换为 Python 字典的库或代码 sn-p?

如果您认为我应该只解析它,欢迎提供任何提示。

【问题讨论】:

  • 一个快速的技巧是将 => 替换为 : 和 :[a-z]+ 替换为 "\1",然后调用 ast.literal_eval 或 json.loads。这是不正确的,因为它忽略了字符串文字,但现在可能已经足够了。
  • 根据他们的文档docs.puppetlabs.com/mcollective/reference/basic/…,他们还可以导出 JSON:-j 标志。
  • 不幸的是,我正在运行的版本中没有。但是,是的,那将是最好的
  • 发送一个 Ruby 哈希的字符串表示真的很奇怪。 Ruby 开发人员应该知道比这样做更好,并且会使用 JSON 或 YAML。您能否向我们展示示例代码,描述您如何进行调用和接收结果数据字符串,以及您如何看待它?您可以使用 cURL 检索数据并完全在 Ruby 或 Python 之外查看数据吗?
  • 它来自 mcollective 的输出,所以您已经看到了从 ruby​​ 或 python 外部调用的字符串。您看到的字符串是该程序的输出,它在 ruby​​ 或 python 之外运行。您可以通过puppetlabs.com/mcollective 了解更多信息

标签: python ruby parsing dictionary hashmap


【解决方案1】:

您可以使用以下命令轻松将其转换为 JSON:

ruby -e 'require "json"; puts JSON.generate({:ruby_hash => "whatever etc..."})'

然后使用 Python 的 JSON 库进行解析。

【讨论】:

  • 这是一种可能性,它确实需要我确保系统上有一个 ruby​​ 解释器,但情况并非总是如此。
【解决方案2】:

实际上,写出足够好的东西来满足我的需求并不算太糟糕。不是最漂亮的东西,但它会为我做的。

# Sometimes MCO gives us a ruby hash as a string, We can coerce this into json then into dictionary
def convert_hash_to_dict(self,ruby_hash):
    dict_str = ruby_hash.replace(":",'"')    # Remove the ruby object key prefix
    dict_str = dict_str.replace("=>",'" : ') # swap the k => v notation, and close any unshut quotes 
    dict_str = dict_str.replace('""','"')    # strip back any double quotes we created to sinlges
    return json.loads(dict_str) 

【讨论】:

  • 为了后代,最后一次替换调用将用key: "替换任何​​空字段,如key: ""
【解决方案3】:

您是否考虑过使用 Ruby 将其序列化为 JSON?这样您就可以使用 Python 的 JSON 库对其进行反序列化。

如果这不是一个选项,您可以使用此库相对轻松地定义自定义结构化语言解析器:https://pypi.python.org/pypi/Parsley

【讨论】:

    猜你喜欢
    • 2015-04-02
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    • 2013-07-06
    • 2014-09-24
    • 2014-07-01
    • 1970-01-01
    • 2016-10-21
    相关资源
    最近更新 更多