2015-04-29 73 views
2

我需要做的是转换是这样的:红宝石字符串转换为特定的阵列格式

"id,name,user[id,email]" 

这个数组:

["id", "name", {"user"=>["id", "email"]}] 

什么是做到这一点的最好方法是什么?我认为像splitscan这样的函数可以提供帮助,但是我并不了解正则表达式来解决这个问题。在生产中必须了解风险,使用eval

+0

您的预期数组无效。 – sawa

+0

什么是上下文?我认为如果你提供了一些关于你想要做什么的背景知识,这可能会有所帮助。 –

+0

@sawa将其编辑为更多拨款。 Ruby将'[“id”,“name”,“user”=> [“id”,“email”]]'转换为'[“id”,“name”,{“user”=> [“id”, “电子邮件”]}]'。在这个例子中,用户成为了数组中的散列。您可以尝试在控制台中键入我的原始数组。 –

回答

3

只是出于好奇:

▶ str = "id,name,user[id,email]" 
▶ eval "[#{str.gsub(/(\w+)\[(.*?)\]/, '{\1=>[\2]}').gsub(/\w+/, ':\0')}]" 
#⇒ [ 
# [0] :id, 
# [1] :name, 
# [2] { 
# :user => [ 
#  [0] :id, 
#  [1] :email 
# ] 
# } 
#] 

Disclamer

UPD安全eval ING(注意,每ASCII \w符号转换到它的从UTF-8宽的一对,以防止注射;不在身边最好的方式,但它工作得很好,除非你有一个宽字符命名红宝石功能):

▶ safe = str.gsub(/\w/) do |e| 
▷ e.each_codepoint.map do |cp| 
▷  cp + 0xFF00 - 0x0020 
▷ end.pack('U') 
▷ end 
#⇒ "id,name,user[id,email]" 
▶ eval "[#{safe.gsub(/(\p{L}+)\[(.*?)\]/, '{\1=>[\2]}').gsub(/\p{L}+/, ':\0')}]" 
#⇒ [ 
# [0] :id, 
# [1] :name, 
# [2] { 
# :user => [ 
#  [0] :id, 
#  [1] :email 
# ] 
# } 
#] 

现在您可以自由地将密钥从宽字符转回ASCII。

+0

我可以做到这一点没有eval? –

+0

当我对'safe'进行评估时,我得到:'未定义的局部变量或方法'name'' –

+0

这个错误只发生在rails中,'irb'不会发生。将解决它。谢谢。 –

0
string = "id,name,user[id,email]" 
parts = string.split(/[\,,\[,\]]/) 
[parts[0], parts[1], {parts[2] => [parts[3], parts[4]]}] 

您可能还需要有一定的验证,或者如果第一个ID应该是一样的第二个不使用的所有部件。

+0

选择性模式中的太多逗号:) – mudasobwa

+0

我还没有完成! –

+0

在我的例子案例工程。但是如果我有用户[id,email],id,name“'?顺序可以改变,字符串的数量可以改变,一切都可以改变,我的例子只是一个模式。@mudasobwa答案解决了我的问题,但我不想使用eval。 –