
Похоже на простую задачу синтаксического анализа. Как правило, подход, который вы собираетесь использовать, заключается в создании рекурсивной функции со следующим общим алгоритмом
base case (input doesn't begin with '[') return the input
recursive case:
split the input on ',' (you will need to find commas only at this level)
for each sub string call this method again with the sub string
return array containing the results from this recursive method
Единственная немного сложная часть здесь - это разделение ввода на один ','. Вы можете написать для этого отдельную функцию, которая будет сканировать строку и вести подсчет открытых скобок - закрытых скобок, замеченных до сих пор. Затем разделяйте запятыми только тогда, когда счетчик равен нулю.
Создайте рекурсивную функцию, которая принимает строку и целочисленное смещение и "считывает" массив. То есть он должен вернуть массив или строку (которую он прочитал) и целочисленное смещение, указывающее после массива. Например:
s = "[[this, is],[a, nested],[array]]"
yourFunc(s, 1) # returns ['this', 'is'] and 11.
yourFunc(s, 2) # returns 'this' and 6.
Затем вы можете вызвать его с помощью другой функции, которая обеспечивает смещение 0 и гарантирует, что окончательное смещение равно длине строки.
Для смеха:
ary = eval("[[this, is],[a, nested],[array]]".gsub(/(\w+?)/, "'\1'") )
=> [["this", "is"], ["a", "nested"], ["array"]]
Отказ от ответственности: вам определенно не следует этого делать, так как eval - ужасная идея, но она быстрая и имеет полезный побочный эффект в виде исключения, если ваши вложенные массивы недействительны.
С YAML вы получите то, что хотите.
Но с вашей строкой есть небольшая проблема. YAML ожидает, что после запятой будет пробел. Итак, нам это нужно
str = "[[this, is], [a, nested], [array]]"
Код:
require 'yaml'
str = "[[this, is],[a, nested],[array]]"
### transform your string in a valid YAML-String
str.gsub!(/(\,)(\S)/, "\1 \2")
YAML::load(str)
# => [["this", "is"], ["a", "nested"], ["array"]]
Вы также можете рассматривать его как почти JSON. Если строки действительно представляют собой только буквы, как в вашем примере, то это будет работать:
JSON.parse(yourarray.gsub(/([a-z]+)/,'""'))
Если бы они могли иметь произвольные символы (кроме [],), вам понадобилось бы немного больше:
JSON.parse("[[this, is],[a, nested],[array]]".gsub(/, /,",").gsub(/([^\[\]\,]+)/,'""'))
Спасибо вам большое за это! Я собирался сойти с ума, пытаясь понять это. :)