Ruby使这个字符串成为数组的最佳方式?

问题描述:

使看起来像散列数组的字符串变成真实数组的最佳方式是什么?Ruby使这个字符串成为数组的最佳方式?

该字符串看起来像这样:[{name:"lol", age:12},{name:"lmao", age:66},{name: "roflcopter", age:99}] 和我需要得到完全相同,但作为一个数组。

输入:(字符串)

'[{name:"lol", age:12},{name:"lmao", age:66},{name: "roflcopter", age:99}]' 

预期输出:(散列数组)

[{name:"lol", age:12},{name:"lmao", age:66},{name: "roflcopter", age:99}] 
+1

输入是什么?你试过什么了? https://*.com/help/how-to-ask – whodini9

+1

数组是什么?名字呢?年龄?都?请给我们一个更详细的例子 –

+0

@ whodini9更新了问题 –

您的字符串非常相似,但不是相当于与JSON相同。这意味着你有三个选择。


1)将其转换为JSON(上游)

你的字符串和正确的JSON字符串之间的唯一区别是,在JSON,所有的键必须用引号引用。如果你在你的字符串格式控制,我建议你改变它是JSON格式:使用JSON.parse

'[{"name":"lol", "age":12},{"name":"lmao", "age":66},{"name": "roflcopter", "age":99}]' 

一旦字符串在此格式下,你可以把它变成散列的数组:

require "json" 
source_string = '[{"name":"lol", "age":12},{"name":"lmao", "age":66},{"name": "roflcopter", "age":99}]' 
data = JSON.parse source_string 
puts data[0] #=> {"name"=>"lol", "age"=>12} 

高度推荐这个过程。包含的JSON解析器以安全的方式处理所有字符串验证。而且,JSON基本上是为了以字符串形式提供数组和散列而设计的。人们会理解这是一个公认的标准。


2)将其转换为JSON(下游)

如果由于某种原因,你不能更新你的源字符串是JSON在默认情况下(也许你与第三方谁拒绝采取工作更好的标准),你可以通过编程的方式修改字符串为正确的JSON格式。其实我去前进,写了一个正则表达式这将对串绕适当的引号:

source_string = '[{name:"lol", age:12},{name:"lmao", age:66},{name: "roflcopter", age:99}]' 
json_string = source_string.gsub /(?<=[{,])\s*(\w+)(?=:)/, '"\1"' 
data = JSON.parse json_string 
puts data[0] #=> {"name"=>"lol", "age"=>12} 

3)使用eval

你的字符串,以目前的格式,是有效的Ruby代码。这意味着你可以使用eval来执行它作为Ruby代码:

data = eval('[{name:"lol", age:12},{name:"lmao", age:66},{name: "roflcopter", age:99}]') 
puts data[0] #=>{name: "lol", age: 12} 

eval的问题,我和其他许多人会强烈反对它的理由是,这是令人难以置信不安全。你说的数据是从POST请求 - 未来如果用户恰好修改发送字符串“系统(‘RM *’)”的要求,你的代码将执行:

eval("system('rm *')") 

哪,你可能猜到了,会擦拭你的硬盘。您可以尝试编写字符串验证以确保字符串在运行之前是安全的,但从安全的角度来看,这种验证不是一件容易的事情,并且eval可能永远是代码中最薄弱的一点。

老实说,你没有理由这样做,特别是因为选项#2是非常直接的。我只提到它,所以你知道要避免它。

+0

太棒了!谢谢百万 –

+0

2)将失败,如果一个字符串包含匹配的正则表达式。 –

+0

@CameronMartin你的意思是有#2的情况下,有效的字符串将不适当'gsub'-ed并会抛出一个错误? – eiko

显然第一选择是不发送数据作为红宝石源代码。但是,如果您确实需要这样做:

如果输入来自信任来源,则可以使用eval

否则,您可以使用ruby parser解析字符串,然后从AST生成阵列和散列。

+1

不幸的是,它不是JSON。钥匙需要用引号包围。这是一个小小的差异,但足以打破解析器。 – eiko

+1

啊,是的,没有看到。 –

+0

是的,也是来源不安全,请删除这个答案。 –