Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Let's say I had the string

"[1,2,[3,4,[5,6]],7]"

How would I parse that into the array

[1,2,[3,4,[5,6]],7]

?

Nesting structures and patterns are completely arbitrary in my usage case.

My current ad-hoc solution involves adding a space after every period and using YAML.load, but I'd like to have a cleaner one if possible.

(One that does not require external libraries if possible)

share|improve this question

3 Answers 3

up vote 15 down vote accepted

That particular example is being parsed correctly using JSON:

s = "[1,2,[3,4,[5,6]],7]"
#=> "[1,2,[3,4,[5,6]],7]"
require 'json'
#=> true
JSON.parse s
#=> [1, 2, [3, 4, [5, 6]], 7]

If that doesn't work, you can try running the string through eval, but you have to ensure that no actual ruby code has been passed, as eval could be used as injection vulnerability.

Edit: Here is a simple recursive, regex based parser, no validation, not tested, not for production use etc:

def my_scan s
  res = []
  s.scan(/((\d+)|(\[(.+)\]))/) do |match|
    if match[1]
      res << match[1].to_i
    elsif match[3]
      res << my_scan(match[3])
    end
  end
  res
end

s = "[1,2,[3,4,[5,6]],7]"
p my_scan(s).first #=> [1, 2, [3, 4, [5, 6]], 7]
share|improve this answer
    
I'd like to use this, but I can't quite get json to run properly on my computer, and in any case it wouldn't be much cleaner than the yaml solution. Is there a way to manually code this parsing? –  Justin L. Dec 18 '10 at 7:48
    
Not sure what do you mean by "not clean", as it is one method call to parse it. You could of course either write a simple regex-based parser of your own, or use dedicated tools, such as treetop.rubyforge.org but neither of those is simple as JSON.parse IMHO. –  Mladen Jablanović Dec 18 '10 at 8:16
    
Oh, and JSON is part of Ruby core lib, at least in 1.9.x. –  Mladen Jablanović Dec 18 '10 at 9:22

The same can be done using Ruby standard libaray YAML as below :

require 'yaml'
s = "[1,2,[3,4,[5,6]],7]"
YAML.load(s)
# => [1, 2, [3, 4, [5, 6]], 7]
share|improve this answer

Use eval

array = eval("[1,2,[3,4,[5,6]],7]")
share|improve this answer
    
This isn't a part my application that I feel safe to leave vulnerable to injections, sorry. –  Justin L. Dec 18 '10 at 7:57
    
@Justin L., A "clean room" + "sandbox" will protect you from the evils of eval: stackoverflow.com/questions/2045324/… . About all that is left to protect against is code that runs a long time; Timeout can take care of that. –  Wayne Conrad Dec 18 '10 at 23:19

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.