我有一个由其他人生成的地图,其数据结构如下:
x = {"city": "London", "country": "England", "region": "Europe"}
我想在Ruby中操纵数据。因此,为了让Ruby能够理解它是一张地图,我需要将所有":"
替换为"=>"
。有没有一种快速的方法可以在一行中实现这一目标?
答案 0 :(得分:13)
您需要安装此gem json
sudo gem install json
require 'json'
JSON.parse('{"city": "London", "country": "England", "region": "Europe"}')
答案 1 :(得分:5)
my_text = 'x = {"city": "London", "country": "England", "region": "Europe"}'
# Replace : with =>
ruby_code = t.gsub(':', '=>')
# Evaluate the string as ruby code
eval ruby_code
# Now you can access the hash
x['city'] # => "London"
答案 2 :(得分:2)
'{"city": "London", "country": "England", "region": "Europe"}'.gsub!(/: /, ' => ')
gsub!
对字符串执行就地全局替换。
答案 3 :(得分:0)
另一种选择,如果你想最大限度地减少你对#eval
(这是理性的事情)的漏洞,那就是使用String#scan
:
quoted = /"(?:\\.|[^\\"])*"/
pairs = '{"city": "London", "country": "England", "region": "Europe"}'.scan(/(#{quoted})\s*:\s*(#{quoted})/)
hash = Hash[ *pairs.flatten.map { |q| eval q } ]
我们仍在使用#eval
,但我们知道我们只是#eval
看起来像带引号的字符串,所以我们是安全的。
由于ruby字符串可以包含任意代码(通过插值奇迹),但我们仍然容易受到攻击:
# arbitrary code evaluation
p eval('"one two #{puts %{Give me a three!}; gets.chomp} four"')
最安全的替代方法是完全绕过#eval
,并使用库来取消引用不允许的字符串
插值。 JSON库(如前所述)就是一个很好的例子。它可能看起来更慢(因为它是
不像#eval
那样优化,但它更安全了。