2015-04-29 2 views
2

Что мне нужно сделать, это преобразовать что-то вроде этого:Рубин преобразовать строку в определенный формат массива

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

в этом массиве:

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

Что такое лучший способ сделать это? Я думаю, что некоторые функции, такие как split или scan, могут помочь, но у меня нет большого количества знаний в регулярном выражении, чтобы решить эту проблему.

+0

Ваш ожидаемый массив недействителен. – sawa

+0

Каков контекст? Я думаю, что если вы предоставите немного больше информации о том, что вы пытаетесь сделать, это может помочь. –

+0

@sawa Отредактировано это, чтобы быть более подходящим. Ruby преобразует '[" id "," name "," user "=> [" id "," email "]]' to '[" 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 
# ] 
# } 
#] 

Юридическая информация: использовать eval в производстве следует понимать риски.

UPD Safe eval Инг (обратите внимание, что каждый 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

Когда я делаю eval на 'safe', я получаю:' undefined local variable или method 'name'' –

+0

Эта ошибка происходит только в rails, на' irb' этого не происходит. Выясните это. Благодарю. –

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

Вы также можете иметь некоторые проверки или не использовать все части, если первый идентификатор должен быть таким же, как второй.

+0

Слишком много запятых в селективном образе :) – mudasobwa

+0

Я еще не закончил! –

+0

В моем примере работает. Но что, если бы у меня был «пользователь» [id, email], id, name «'? Порядок может измениться, количество строк может измениться, все может измениться, мой пример - всего лишь шаблон.Ответ @mudasobwa решает мою проблему, но я не хотел использовать eval. –

Смежные вопросы