这看起来像 JavaScript Object Notation (JSON)。您可以解析驻留在某个变量中的 JSON,例如 json_string
,如下所示:
require 'json'
JSON.parse(json_string)
如果您使用的是旧版 Ruby,则可能需要安装 json gem。
Ruby 的其他 JSON 实现可能更适合某些用例:
YAJL C Ruby 绑定
JSON::流
只是为了扩展答案与如何处理解析的对象:
# JSON Parsing example
require "rubygems" # don't need this if you're Ruby v1.9.3 or higher
require "json"
string = '{"desc":{"someKey":"someValue","anotherKey":"value"},"main_item":{"stats":{"a":8,"b":12,"c":10}}}'
parsed = JSON.parse(string) # returns a hash
p parsed["desc"]["someKey"]
p parsed["main_item"]["stats"]["a"]
# Read JSON from a file, iterate over objects
file = open("shops.json")
json = file.read
parsed = JSON.parse(json)
parsed["shop"].each do |shop|
p shop["id"]
end
'{ "a": "bob" }'
有效。 "{ 'a': 'bob' }"
不是。
JSON.parse
包装在 JSON::ParserError
的救援块中。
JSON.parse("[#{value}]")[0]
以避免错误 A JSON text must at least contain two octets!
从 Ruby v1.9.3 开始,您无需安装任何 Gem 即可解析 JSON,只需使用 require 'json'
:
require 'json'
json = JSON.parse '{"foo":"bar", "ping":"pong"}'
puts json['foo'] # prints "bar"
请参阅 Ruby-Doc 中的 JSON。
它看起来像一个 JSON 字符串。您可以使用许多 JSON 库之一,它就像这样做一样简单:
JSON.parse(string)
这有点晚了,但我遇到了一些有趣的东西,似乎很重要。
我不小心写了这段代码,它似乎工作:
require 'yaml'
CONFIG_FILE = ENV['CONFIG_FILE'] # path to a JSON config file
configs = YAML.load_file("#{CONFIG_FILE}")
puts configs['desc']['someKey']
由于我使用的是 YAML 库,我很惊讶地看到它有效,但它有效。
之所以重要,是因为 yaml
是 Ruby 内置的,因此无需安装 gem。
我使用的是 1.8.x 和 1.9.x 版本 - 所以 json
库不是内置的,但它在 2.x 版本中。
所以从技术上讲 - 这是提取低于 2.0 版本数据的最简单方法。
在这里看不到任何提到直接解析为哈希以外的对象的答案,但可以使用文档记录不佳的 object_class 选项(请参阅 https://ruby-doc.org/stdlib-2.7.1/libdoc/json/rdoc/JSON.html):
JSON.parse('{"foo":{"bar": 2}}', object_class: OpenStruct).foo.bar
=> 2
阅读该选项的更好方法是“json 对象变成的 ruby 类”,这解释了为什么它默认为 Hash。同样,对于 json 数组,还有一个 array_class 选项。
如果您想反序列化为您自己的类而不是 OpenStruct,则不需要做很多工作就可以实现以下目标:
require 'json'
# result is an instance of MyClass
result = JSON.parse(some_json_string, object_class: MyClass)
您所要做的就是提供一个零参数构造函数并实现 JSON.parse
将调用的 #[]=
方法。如果您不想公开它,将其设为私有就足够了:
class MyClass
attr_reader :a, :b
private
def []=(key, value)
case key
when 'a' then @a = value
when 'b' then @b = value
end
end
end
在 irb 中尝试:
> JSON.parse('{"a":1, "b":2}', object_class: MyClass)
=> #<MyClass:0x00007fe00913ae98 @a=1, @b=2>
这种方法的一个警告是它只适用于平面结构,因为 object_class
参数确实告诉解析器它应该使用哪个类来反序列化字符串中的 JSON 对象而不是 Hash
(参见类似的参数 array_class
JSON 数组的类似操作)。对于嵌套结构,这意味着您将使用相同的类来表示所有层:
> JSON.parse('{"a":1, "b":{ "a": 32 }}', object_class: MyClass)
=> #<MyClass:0x00007fb5110b2b38 @a=1, @b=#<MyClass:0x00007fb5110b2908 @a=32>>
JSON.parse(string, symbolize_names: true) #=> {key: :value}
require 'json'
。