2008-09-01 8 views

Répondre

11

Vous obtiendrez ce que vous voulez avec YAML.

Mais il y a un petit problème avec votre chaîne. YAML s'attend à ce qu'il y ait un espace derrière la virgule. Nous avons donc besoin de cette

str = "[[this, is], [a, nested], [array]]" 

code:

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"]] 
+0

Merci beaucoup pour ça! J'étais sur le point de devenir fou en essayant de comprendre cela. :) – CalebHC

+0

+1 pour une utilisation intelligente d'une bibliothèque existante et regex – BF4

0

On dirait une tâche d'analyse syntaxique de base. En général, l'approche que vous allez vouloir prendre est de créer une fonction récursive avec l'algorithme général suivant

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 

La seule partie slighlty délicate ici est divisant l'entrée sur un seul « ». Vous pourriez écrire une fonction séparée pour cela qui balayerait la chaîne et garderait le compte des openbrackets - des banderoles fermées vues jusqu'ici. Alors seulement diviser sur les virgules lorsque le compte est égal à zéro.

0

Crée une fonction récursive qui prend la chaîne et un décalage entier, et "lit" un tableau. En d'autres termes, renvoyez un tableau ou une chaîne (qu'il a lu) et un décalage d'entier pointant après le tableau. Par exemple:

s = "[[this, is],[a, nested],[array]]" 

yourFunc(s, 1) # returns ['this', 'is'] and 11. 
yourFunc(s, 2) # returns 'this' and 6. 

Ensuite, vous pouvez l'appeler avec une autre fonction qui fournit un décalage de 0, et fait en sorte que la finition offset est la longueur de la chaîne.

3

Pour rire:

ary = eval("[[this, is],[a, nested],[array]]".gsub(/(\w+?)/, "'\\1'")) 
=> [["this", "is"], ["a", "nested"], ["array"]] 

Avertissement: Vous ne devez certainement pas faire cela comme eval est une très mauvaise idée, mais il est rapide et a l'effet secondaire utile de lancer une exception si vos tableaux imbriqués Aren 't valable

3

Vous pouvez également le traiter comme presque JSON. Si les chaînes sont vraiment que des lettres, comme dans votre exemple, cela fonctionnera:

JSON.parse(yourarray.gsub(/([a-z]+)/,'"\1"')) 

Si l'on pouvait avoir des caractères arbitraires (autres que [],), vous auriez besoin d'un peu plus:

JSON.parse("[[this, is],[a, nested],[array]]".gsub(/, /,",").gsub(/([^\[\]\,]+)/,'"\1"')) 
Questions connexes