将拼音字符串拆分为多个哈希的正则表达式



我在Postgresql数据库的jsonb列中有一个这样的字符串:

"{"monday"=>"{:start_time=>9.0, :end_time=>10.5}"},{"tuesday"=>"{:start_time=>8.5, :end_time=>10.0}"},{"wednesday"=>"{:start_time=>8.5, :end_time=>10.0}"}"

现在我想使用正则表达式让它看起来像这样:

[{"monday"=>"{:start_time=>9.0, :end_time=>10.5}"}, 
{"tuesday"=>"{:start_time=>8.5, :end_time=>10.0}"},
{"wednesday"=>"{:start_time=>8.5, :end_time=>10.0}"}
]

我正在尝试使用带有正则表达式的方法拆分来完成任务。但是,我仍然无法弄清楚如何仅拆分字符串中右大括号之后的逗号。 我能想到的就是用 ruby 中的扫描方法对其进行测试,如下所示:

test =  "{"monday"=>"{:start_time=>9.0, :end_time=>10.5}"},{"tuesday"=>"{:start_time=>8.5, :end_time=>10.0}"},{"wednesday"=>"{:start_time=>8.5, :end_time=>10.0}"}"
result = test.scan(/"},/)
=> result = [""},", ""},"]

看起来我走在正确的轨道上,但我被困在这里。任何建议将不胜感激。

更新谢谢丁曼先生的周到解释。我将数据库改回hstore,并在将数据传递到后端之前使用JSON.stringify。 在这里和那里进行一些扭曲,我终于可以按照您的建议获得我想要的哈希:

{"monday"=>{"start_time"=>9, "end_time"=>10.5}, "tuesday"=>{"start_time"=>8.5, "end_time"=>10}, "wednesday"=>{"start_time"=>8.5, "end_time"=>10}}

.但是,将其保存到数据库后,哈希的所有值都将序列化为字符串:

{
"monday" => "{"start_time"=>9, "end_time"=>10.5}",
"tuesday" => "{"start_time"=>7, "end_time"=>8.5}",
"wednesday" => "{"start_time"=>7, "end_time"=>8.5}"
}

我知道我可以使用 eval 将它们转换回哈希。但是,有什么方法可以让我将这些值也保存为数据库中的哈希值,或者由于 Hstore 机制而不能?

看起来您尝试创建自己的 JSON 序列化程序,而不是使用 Ruby 附带的序列化程序。或者,也许您没有意识到JSON是一个东西,并且想要存储哈希数组并尝试发明自己的哈希数组。无论哪种方式,这都不是一条好路。

这是您的定义,检索后将保留为字符串。它似乎是哈希数组的元素,没有周围的数组[]

foo = "{"monday"=>"{:start_time=>9.0, :end_time=>10.5}"},{"tuesday"=>"{:start_time=>8.5, :end_time=>10.0}"},{"wednesday"=>"{:start_time=>8.5, :end_time=>10.0}"}"

它仍然是一个字符串:

foo.class # => String

可以将其重新修改为可以评估的形式,并将其重新转换为哈希数组,但它并不简单,也不干净,方便或优雅。

我怀疑你的原始对象看起来像这样:

foo = {"monday"=>{:start_time=>9.0, :end_time=>10.5}},{"tuesday"=>{:start_time=>8.5, :end_time=>10.0}},{"wednesday"=>{:start_time=>8.5, :end_time=>10.0}}
# => [{"monday"=>{:start_time=>9.0, :end_time=>10.5}},
#     {"tuesday"=>{:start_time=>8.5, :end_time=>10.0}},
#     {"wednesday"=>{:start_time=>8.5, :end_time=>10.0}}]

这是一个数组:

foo.class # => Array

它现在是一个数组,因为你有多个用逗号(,)分隔的哈希元素,Ruby 在分配给单个变量时将其解释为数组。这将是一个视觉上不那么令人困惑的示例:

foo = {a: 1}, {a: 2} # => [{:a=>1}, {:a=>2}]
foo.class  # => Array
foo.first.class # => Hash

回到foo中的哈希数组:从此开始,很容易让 JSON 类将其序列化为可以存储在数据库中的字符串,然后检索并重新解析回 Ruby 对象:

require 'json'
foo.to_json

foo.to_json将生成如下所示的序列化字符串:

[{"monday":{"start_time":9.0,"end_time":10.5}},{"tuesday":{"start_time":8.5,"end_time":10.0}},{"wednesday":{"start_time":8.5,"end_time":10.0}}]

而且,给定该字符串,JSON 可以重建对象:

bar = JSON.parse(foo.to_json)
# => [{"monday"=>{"start_time"=>9.0, "end_time"=>10.5}},
#     {"tuesday"=>{"start_time"=>8.5, "end_time"=>10.0}},
#     {"wednesday"=>{"start_time"=>8.5, "end_time"=>10.0}}]

请注意,没有必要使用parseto_json.该类足够聪明,可以识别参数是字符串、数组还是哈希,并分别解析或序列化:

JSON[JSON[foo]]
# => [{"monday"=>{"start_time"=>9.0, "end_time"=>10.5}},
#     {"tuesday"=>{"start_time"=>8.5, "end_time"=>10.0}},
#     {"wednesday"=>{"start_time"=>8.5, "end_time"=>10.0}}]

此时,您已准备好将值存储到数据库中的字符串类型字段中,然后稍后检索它们并重复使用它们。

如果您希望搜索或操作这些存储的JSON字符串,我建议您重新考虑一下。虽然现代 DBM 可以在 JSON 内部搜索并生成它,但您最好有一个单独的键和值表。它更快、更灵活。

最后回答您的问题,如何转换字符串以获取键和值:

foo = "{"monday"=>"{:start_time=>9.0, :end_time=>10.5}"},{"tuesday"=>"{:start_time=>8.5, :end_time=>10.0}"},{"wednesday"=>"{:start_time=>8.5, :end_time=>10.0}"}"
bar = eval('[' + foo.gsub(/"([{}])/, '1') + ']')
bar
# => [{"monday"=>{:start_time=>9.0, :end_time=>10.5}},
#     {"tuesday"=>{:start_time=>8.5, :end_time=>10.0}},
#     {"wednesday"=>{:start_time=>8.5, :end_time=>10.0}}]
bar.map { |h| [h.keys, h.values.first.keys] }
# => [[["monday"], [:start_time, :end_time]],
#     [["tuesday"], [:start_time, :end_time]],
#     [["wednesday"], [:start_time, :end_time]]]

这暗示哈希数组也不是正确的结构。一个简单的哈希就足够了:

foo = {
"monday"=>{:start_time=>9.0, :end_time=>10.5},
"tuesday"=>{:start_time=>8.5, :end_time=>10.0},
"wednesday"=>{:start_time=>8.5, :end_time=>10.0}
}
require 'json'
bar = JSON[JSON[foo]] # imitate a round-trip to/from the DB
bar.keys # => ["monday", "tuesday", "wednesday"]
bar.values # => [{"start_time"=>9.0, "end_time"=>10.5}, {"start_time"=>8.5, "end_time"=>10.0}, {"start_time"=>8.5, "end_time"=>10.0}]

最新更新