将一个Ruby哈希字符串转换为Python字典。

8
我正在处理一些命令输出,它作为 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字典吗?
如果你认为我应该自己解析它,欢迎提供任何建议。

1
一个快速的解决方法是将 => 替换为 :,将 :[a-z]+ 替换为 "\1",然后调用 ast.literal_eval 或 json.loads。虽然这种方法忽略了字符串字面量,但现在可能已经足够好了。 - Antimony
根据他们的文档http://docs.puppetlabs.com/mcollective/reference/basic/basic_cli_usage.html,他们也可以导出JSON:`-j`标志。 - georg
很遗憾,这不是我正在运行的版本。但是,确实那样做会更好。 - joeButler
1
真的很奇怪,为什么会发送 Ruby 哈希表的字符串表示形式。Ruby 开发人员应该知道更好的方法,而不是使用 JSON 或 YAML。您能否展示一下代码示例,描述您如何进行调用并接收结果数据字符串,以及您如何查看它?您能否使用 cURL 检索数据并在 Ruby 或 Python 之外完全查看它? - the Tin Man
这是来自mcollective的输出,因此您已经看到了从ruby或python之外调用的字符串。您看到的字符串是该程序在ruby或python之外运行时的输出。您可以从http://puppetlabs.com/mcollective了解更多信息。 - joeButler
3个回答

7
您可以使用以下命令轻松将其转换为JSON格式:
ruby -e 'require "json"; puts JSON.generate({:ruby_hash => "whatever etc..."})'

然后使用Python的JSON库来解析它。

这是一种可能性,但需要确保系统上有Ruby解释器,而这并不总是情况。 - joeButler

7

实际上,为我的需求写一些足够好的东西并不那么困难。虽然它不是最美观的东西,但对我来说已经足够。

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

1
为了后代,最后的替换调用将替换任何空字段,例如 key: ""key: " - Steampunkery

4
你曾考虑过使用Ruby来将此转换为JSON吗?这样你就可以使用Python的JSON库进行反序列化。如果这不可行,你可以使用这个库相对轻松地定义一个自定义结构化语言解析器:https://pypi.python.org/pypi/Parsley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接