Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 如何将已生成哈希字符串的内容转换为哈希?_Ruby_Hash - Fatal编程技术网

Ruby 如何将已生成哈希字符串的内容转换为哈希?

Ruby 如何将已生成哈希字符串的内容转换为哈希?,ruby,hash,Ruby,Hash,我有一个从Rails数据库中提取的“散列字符串”,我必须将其作为散列处理。我怎么做这个 str=“{H:50,Q:25,D:10,N:5,p:1}” 这件事 str={H:50,Q:25,D:10,N:5,p:1}你可以试试它eval(str) 扫描字符串以查找键/值对 避免对可能受污染的字符串运行eval的一种方法是使用解析字符串中的键和值,然后使用and将结果数组转换为哈希。如果愿意,还可以使用将结果键从字符串转换为符号,并使用将每个值转换为整数 用于扫描键和值的正则表达式已根据示例输入进行

我有一个从Rails数据库中提取的“散列字符串”,我必须将其作为散列处理。我怎么做这个

str=“{H:50,Q:25,D:10,N:5,p:1}”

这件事

str={H:50,Q:25,D:10,N:5,p:1}
你可以试试它
eval(str)

扫描字符串以查找键/值对 避免对可能受污染的字符串运行eval的一种方法是使用解析字符串中的键和值,然后使用and将结果数组转换为哈希。如果愿意,还可以使用将结果键从字符串转换为符号,并使用将每个值转换为整数

用于扫描键和值的正则表达式已根据示例输入进行了调整,因此可能需要针对其他数据对其进行修改。然而,它确实适用于您发布的示例

解析为JSON 在评论中,OP表示他们不想将字符串解析为JSON。作为一种通用方法,它在概念上比上面的解决方案更简单(也更短),因此我将在这里为其他访问者介绍它

主要的技巧是,除非您引用键,否则OP发布的输入不会解析为JSON。我们可以使用的块形式轻松地做到这一点,然后将生成的有效JSON解析为Ruby哈希

require 'json'

str = '{ H: 50, Q: 25, D: 10, N: 5, P: 1 }'
JSON.parse(str.gsub(/\p{Upper}(?=:)/) { %("#{$&}") }).transform_keys &:to_sym
#=> {:H=>50, :Q=>25, :D=>10, :N=>5, :P=>1}

这两种方法在发布的示例中同样有效。将数据解析为JSON似乎增加了有用的输入验证层和程序员便利性,但个别用例可能会有所不同。

将非单词字符上的字符串拆分为数组。这将拆分1个或多个非字母、数字或下划线的字符。仅从数组中选择单词(这将删除第一个空字符串)。将数组切片为成对的键和值。将键转换为符号,将值转换为整数。将结果转换为哈希。整个香肠的外观如下:

str = '{ H: 50, Q: 25, D: 10, N: 5, P: 1 }'
a = str.split(/\W+/).grep(/\w+/).each_slice(2).map{ |k, v| [k.to_sym, v.to_i] }.to_h
puts a.inspect
# {:H=>50, :Q=>25, :D=>10, :N=>5, :P=>1}
它采用的形式是,接受一个参数而不接受块,返回一个可以链接到的枚举数。这种形式的
gsub
只生成匹配项;它不能替代

这种构造的一个优点是避免了创建临时数组

正则表达式可以在自由间距模式下编写,以使其能够自文档化

/
(\S+)  # match 1+ characters other than whitespaces, save to capture group 1 
:[ ]+  # match ':' followed by 1+ spaces
(\d+)  # match 1+ digits, save to capture group 2
/x     # free-spacing regex definition mode

这回答了你的问题吗?不太好,肯。我不想在我的环境中使用JSON解析和eval来实现我想要的结果。不幸的是,这些答案都不起作用。我已经检查过了。@VictorPark您是否坚持使用这种格式,或者是否可以切换到JSON?
eval
几乎总是错误的工具,因为它极易导致远程代码执行漏洞,攻击者可以让您的应用程序执行攻击者提供的任何代码。其他答案中提出的受限解析器通常更安全。我同意。不幸的是,eval不是一个很好的工具,谢谢。在我看来,这是最好的答案!
str = '{ H: 50, Q: 25, D: 10, N: 5, P: 1 }'
a = str.split(/\W+/).grep(/\w+/).each_slice(2).map{ |k, v| [k.to_sym, v.to_i] }.to_h
puts a.inspect
# {:H=>50, :Q=>25, :D=>10, :N=>5, :P=>1}
str = "{ H: 50, Q: 25, D: 10, N: 5, P: 1 }"
str.gsub(/(\S+): +(\d+)/).with_object({}) { |_,h| h[$1.to_sym] = $2.to_i }
  #=> {:H=>50, :Q=>25, :D=>10, :N=>5, :P=>1}
/
(\S+)  # match 1+ characters other than whitespaces, save to capture group 1 
:[ ]+  # match ':' followed by 1+ spaces
(\d+)  # match 1+ digits, save to capture group 2
/x     # free-spacing regex definition mode