我需要做的是转换是这样的:红宝石字符串转换为特定的阵列格式
"id,name,user[id,email]"
这个数组:
["id", "name", {"user"=>["id", "email"]}]
什么是做到这一点的最好方法是什么?我认为像split
或scan
这样的函数可以提供帮助,但是我并不了解正则表达式来解决这个问题。在生产中必须了解风险,使用eval
:
我需要做的是转换是这样的:红宝石字符串转换为特定的阵列格式
"id,name,user[id,email]"
这个数组:
["id", "name", {"user"=>["id", "email"]}]
什么是做到这一点的最好方法是什么?我认为像split
或scan
这样的函数可以提供帮助,但是我并不了解正则表达式来解决这个问题。在生产中必须了解风险,使用eval
:
只是出于好奇:
▶ 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。
我可以做到这一点没有eval? –
当我对'safe'进行评估时,我得到:'未定义的局部变量或方法'name'' –
这个错误只发生在rails中,'irb'不会发生。将解决它。谢谢。 –
string = "id,name,user[id,email]"
parts = string.split(/[\,,\[,\]]/)
[parts[0], parts[1], {parts[2] => [parts[3], parts[4]]}]
您可能还需要有一定的验证,或者如果第一个ID应该是一样的第二个不使用的所有部件。
选择性模式中的太多逗号:) – mudasobwa
我还没有完成! –
在我的例子案例工程。但是如果我有用户[id,email],id,name“'?顺序可以改变,字符串的数量可以改变,一切都可以改变,我的例子只是一个模式。@mudasobwa答案解决了我的问题,但我不想使用eval。 –
您的预期数组无效。 – sawa
什么是上下文?我认为如果你提供了一些关于你想要做什么的背景知识,这可能会有所帮助。 –
@sawa将其编辑为更多拨款。 Ruby将'[“id”,“name”,“user”=> [“id”,“email”]]'转换为'[“id”,“name”,{“user”=> [“id”, “电子邮件”]}]'。在这个例子中,用户成为了数组中的散列。您可以尝试在控制台中键入我的原始数组。 –