在 Ruby 中解析 JSON 字符串

发布于 2024-10-26 01:32:23 字数 188 浏览 2 评论 0 原文

我有一个想要在 Ruby 中解析的字符串:

string = '{"desc":{"someKey":"someValue","anotherKey":"value"},"main_item":{"stats":{"a":8,"b":12,"c":10}}}'

有没有一种简单的方法来提取数据?

I have a string that I want to parse in Ruby:

string = '{"desc":{"someKey":"someValue","anotherKey":"value"},"main_item":{"stats":{"a":8,"b":12,"c":10}}}'

Is there an easy way to extract the data?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

南冥有猫 2024-11-02 01:32:23

这看起来像 JavaScript 对象表示法 (JSON)。您可以解析驻留在某个变量中的 JSON,例如 json_string,如下所示:

require 'json'
JSON.parse(json_string)

如果您使用的是较旧的 Ruby,则可能需要安装 json gem


还有其他用于 Ruby 的 JSON 实现可能更适合某些用例:

This looks like JavaScript Object Notation (JSON). You can parse JSON that resides in some variable, e.g. json_string, like so:

require 'json'
JSON.parse(json_string)

If you’re using an older Ruby, you may need to install the json gem.


There are also other implementations of JSON for Ruby that may fit some use-cases better:

七颜 2024-11-02 01:32:23

只是为了稍微扩展一下如何处理解析对象的答案:

# 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

Just to extend the answers a bit with what to do with the parsed object:

# 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
说谎友 2024-11-02 01:32:23

从 Ruby v1.9.3 开始,您不需要安装任何 Gems 来解析 JSON,只需使用 require 'json'

require 'json'

json = JSON.parse '{"foo":"bar", "ping":"pong"}'
puts json['foo'] # prints "bar"

请参阅 JSON 位于 Ruby-Doc。

As of Ruby v1.9.3 you don't need to install any Gems in order to parse JSON, simply use require 'json':

require 'json'

json = JSON.parse '{"foo":"bar", "ping":"pong"}'
puts json['foo'] # prints "bar"

See JSON at Ruby-Doc.

赢得她心 2024-11-02 01:32:23

它看起来像一个 JSON 字符串。您可以使用众多 JSON 库之一,就像执行以下操作一样简单:

JSON.parse(string)

It looks like a JSON string. You can use one of many JSON libraries and it's as simple as doing:

JSON.parse(string)
淡淡的优雅 2024-11-02 01:32:23

这里没有看到任何提到直接解析为哈希以外的对象的答案,但可以使用记录不充分的 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 选项。

Don't see any answers here that mention parsing directly to an object other than a Hash, but it is possible using the poorly-documented object_class option(see https://ruby-doc.org/stdlib-2.7.1/libdoc/json/rdoc/JSON.html):

JSON.parse('{"foo":{"bar": 2}}', object_class: OpenStruct).foo.bar
=> 2

The better way to read that option is "The ruby class that a json object turns into", which explains why it defaults to Hash. Likewise, there is an array_class option for json arrays.

若相惜即相离 2024-11-02 01:32:23

虽然有点晚了,但我遇到了一些有趣的事情,似乎对我的贡献很重要。

我不小心写了这段代码,它似乎有效:

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 版本的数据的最简单方法。

This is a bit late but I ran into something interesting that seems important to contribute.

I accidentally wrote this code, and it seems to work:

require 'yaml'
CONFIG_FILE = ENV['CONFIG_FILE'] # path to a JSON config file 
configs = YAML.load_file("#{CONFIG_FILE}")
puts configs['desc']['someKey']

I was surprised to see it works since I am using the YAML library, but it works.

The reason why it is important is that yaml comes built-in with Ruby so there's no gem install.

I am using versions 1.8.x and 1.9.x - so the json library is not built in, but it is in version 2.x.

So technically - this is the easiest way to extract the data in version lower than 2.0.

海的爱人是光 2024-11-02 01:32:23

我建议使用 Oj,因为它比标准 JSON 库快得多。

https://github.com/ohler55/oj

(在此处查看性能比较

I suggest Oj as it is waaaaaay faster than the standard JSON library.

https://github.com/ohler55/oj

(see performance comparisons here)

想念有你 2024-11-02 01:32:23

如果您想反序列化为您自己的类而不是 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>>

If you want to deserialise to your own class instead of OpenStruct it doesn't take a lot of work to make the following possible:

require 'json'
# result is an instance of MyClass
result = JSON.parse(some_json_string, object_class: MyClass)

All you have to do is to provide a zero-argument constructor and implement the #[]= method which JSON.parse will call. If you don't want to expose it, it's sufficient to let it be private:

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

Trying it out in irb:

> JSON.parse('{"a":1, "b":2}', object_class: MyClass)
=> #<MyClass:0x00007fe00913ae98 @a=1, @b=2>

A caveat with this approach is that it only works for flat structures, because the object_class argument really tells the parser what class it should use to deserialise JSON objects in the string instead of Hash (see the similar argument array_class for the analogous operation for JSON arrays). For nested structures this will mean you will use the same class to represent all layers:

> JSON.parse('{"a":1, "b":{ "a": 32 }}', object_class: MyClass)
=> #<MyClass:0x00007fb5110b2b38 @a=1, @b=#<MyClass:0x00007fb5110b2908 @a=32>>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文