簡體   English   中英

在 Ruby 中解析 JSON 字符串

[英]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 的版本中提取數據的最簡單方法。

我建議使用 Oj,因為它比標准的 JSON 庫快得多。

https://github.com/ohler55/oj

請參閱此處的性能比較

我有一個要在 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM