[英]Parsing a JSON string in Ruby
我有一個要在 Ruby 中解析的字符串:
string = '{"desc":{"someKey":"someValue","anotherKey":"value"},"main_item":{"stats":{"a":8,"b":12,"c":10}}}'
有沒有簡單的方法來提取數據?
這看起來像JavaScript Object Notation (JSON) 。 您可以解析駐留在某個變量中的 JSON,例如json_string
,如下所示:
require 'json'
JSON.parse(json_string)
如果您使用的是舊版 Ruby,則可能需要安裝json gem 。
還有其他適用於 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
從 Ruby v1.9.3 開始,您不需要安裝任何 Gems 來解析 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)
在這里看不到任何提到直接解析為哈希以外的對象的答案,但是可以使用記錄不完整的 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 選項。
這有點晚了,但我遇到了一些有趣的事情,這些事情似乎很重要。
我不小心寫了這段代碼,它似乎有效:
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 的版本中提取數據的最簡單方法。
我有一個要在 Ruby 中解析的字符串:
string = '{"desc":{"someKey":"someValue","anotherKey":"value"},"main_item":{"stats":{"a":8,"b":12,"c":10}}}'
有沒有簡單的方法來提取數據?
如果你想反序列化到你自己的類而不是 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>>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.