如何在Ruby中解析以符号为键而不是字符串的json字符串数据?

How to parse json string data having symbols as key instead of string in Ruby?

提问人:Mohammad Arif 提问时间:7/28/2023 最后编辑:smathyMohammad Arif 更新时间:7/28/2023 访问量:68

问:

下面是 json 字符串示例

json = "{:status=>\"ok\", :hitcount=>\"1\", :request_date=>Wed, 10 Oct 2019 00:00:00 +0000}"

我已经尝试了下面提到的片段,但这不起作用并给出错误JSON::ParserError (765: unexpected token at

require 'json'
JSON.parse(json)
json ruby-on-rails ruby json解析器

评论

7赞 smathy 7/28/2023
我的意思是,你不能将该字符串解析为 JSON,因为它不是 JSON。它是 ruby,它被变成了一个带有 / 的字符串。to_sinspect

答:

0赞 Narfanator 7/28/2023 #1

不幸的是,JSON 不能表示 Ruby 符号。JSON 还要求键和值都用引号引起来,因此您提供的内容不是有效的 JSON,并且会破坏 JSON 解析器。你只需要:

json = "{\"status\": \"ok\", \"hitcount\": \"1\", \"request_date\": \"Wed, 10 Oct 2019 00:00:00 +0000\"}"

然后 Ruby JSON 解析器(感谢@engineersmnky!)有一个漂亮的功能:

JSON.parse(json, symbolize_name: true)

评论

2赞 engineersmnky 7/28/2023
您没有提供有关如何从当前结果到您提议的结果的解释,即便如此,这也将中断。JSON 不知道如何解析 ruby hashrocket 语法,因此您需要将 “=>” 替换为 “:”。也接受参数,不需要轨道和块转换,例如JSON#parsesymbolize_namesJSON.parse(json, {symbolize_names: true})
0赞 Narfanator 7/28/2023
啊,谢谢!我错过了这个变化,我不知道JSON选项。
0赞 vitamin-d 7/28/2023 #2

它看起来确实像一个格式问题。例如,如果你有一个具有相同数据的普通哈希值,并将其转换为JSON,它看起来会有点不同:

require 'json'
# Original value in post
# json = "{:status=>\"ok\", :hitcount=>\"1\", :request_date=>Wed, 10 Oct 2019 00:00:00 +0000}"

hash = {:status=>"ok", :hitcount=>"1", :request_date=>"Wed, 10 Oct 2019 00:00:00 +0000"}
json = hash.to_json
puts json  # {"status":"ok","hitcount":"1","request_date":"Wed, 10 Oct 2019 00:00:00 +0000"}


parsed = JSON.parse(json)
puts parsed  # {"status"=>"ok", "hitcount"=>"1", "request_date"=>"Wed, 10 Oct 2019 00:00:00 +0000"}

你可以在这里明白我的意思:https://onlinegdb.com/tr6JVAV6y

因此,我猜您需要查看JSON的来源,并以适当的格式发送。

-1赞 oldmanowl 7/28/2023 #3

您可以使用此字符串转换为 ruby 代码(哈希)。您会遇到一些问题,因为日期没有引用。(我只是让 ChatGPT 为它编写正则表达式)。这会将您的字符串转换为正确的 ruby 哈希值:eval()

json = "{:status=>\"ok\", :hitcount=>\"1\", :request_date=>Wed, 10 Oct 2019 00:00:00 +0000}" 

fixed_string = json.gsub(/:request_date=>(\w+,\s\d+\s\w+\s\d+\s\d+:\d+:\d+\s\+\d+)/, ':request_date=>"\1"')

hash = eval(fixed_string)

输出:

{:status=>"ok", :hitcount=>"1", :request_date=>"Wed, 10 Oct 2019 00:00:00 +0000"}

请注意,如果您无法控制输入,并且问题似乎出在输出的生成方式上,那么使用 eval 会带来安全风险。