Вы можете использовать что-то вроде Parslet для написания парсера.Вот пример, который я написал на основе грамматики JSON от http://www.json.org/
require 'parslet'
#This needs a few more 'as' calls to annotate the output
class JSONParser < Parslet::Parser
rule(:space) { match('[\s\n]').repeat(1)}
rule(:space?) { space.maybe }
rule(:digit) { match('[0-9]') }
rule(:hexdigit) { match('[0-9a-fA-F]') }
rule(:number) { space? >> str('-').maybe >>
(str('0') | (match('[1-9]') >> digit.repeat)) >>
(str('.') >> digit.repeat).maybe >>
((str('e')| str('E')) >> (str('+')|str('-')).maybe >> digit.repeat ).maybe }
rule(:escaped_character) { str('\\') >> (match('["\\\\/bfnrt]') | (str('u') >> hexdigit.repeat(4,4))) }
rule(:string) { space? >> str('"') >> (match('[^\"\\\\]') | escaped_character).repeat >> str('"') }
rule(:value) { space? >> (string | number | object | array | str('true') | str('false') | str('null')) }
rule(:pair) { string >> str(":") >> value }
rule(:pair_list) { pair >> (space? >> str(',') >> pair).repeat }
rule(:object) { str('{') >> space? >> pair_list.maybe >> space? >> str('}') }
rule(:value_list) { value >> (space? >> str(',') >> value).repeat }
rule(:array) { space? >> str('[') >> space? >> value_list.maybe >> space? >> str(']') >> space?}
rule(:json) { value.as('value') >> (space? >> str(',') >> value.as('value')).repeat }
root(:json)
end
# I've changed your doc to be a list of JSON values
doc = '[
{ "foo":
{"bar":"foo",
"bar": [
{"foo":"bar", "foo":"bar"}
]
}
}
],
{"foo":"bar"},{"foo":"bar"}'
puts JSONParser.new.parse(doc)[1..-1].map{|value| value["value"]}.join(",")
# => {"foo":"bar"},{"foo":"bar"}
Однако, поскольку ваш документ не является допустимым JSON (насколько я знаю) ... тогда вы можете изменить вышеприведенное ...
require 'parslet'
class YourFileParser < Parslet::Parser
rule(:space) { match('[\s\n]').repeat(1)}
rule(:space?) { space.maybe }
rule(:digit) { match('[0-9]') }
rule(:hexdigit) { match('[0-9a-fA-F]') }
rule(:number) { space? >> str('-').maybe >>
(str('0') | (match('[1-9]') >> digit.repeat)) >>
(str('.') >> digit.repeat).maybe >>
((str('e')| str('E')) >> (str('+')|str('-')).maybe >> digit.repeat ).maybe }
rule(:escaped_character) { str('\\') >> (match('["\\\\/bfnrt]') | (str('u') >> hexdigit.repeat(4,4))) }
rule(:string) { space? >> str('"') >> (match('[^\"\\\\]') | escaped_character).repeat >> str('"') }
rule(:value) { space? >> (string | number | object | array | str('true') | str('false') | str('null')) }
rule(:pair) { string >> str(":") >> value }
rule(:pair_list) { (pair|value) >> (space? >> str(',') >> (pair|value)).repeat }
rule(:object) { str('{') >> space? >> pair_list.maybe >> space? >> str('}') }
rule(:value_list) { (pair|value) >> (space? >> str(',') >> (pair|value)).repeat }
rule(:array) { space? >> str('[') >> space? >> value_list.maybe >> space? >> str(']') >> space?}
rule(:yourdoc) { (pair|value).as('value') >> (space? >> str(',') >> (pair|value).as('value')).repeat }
root(:yourdoc)
end
doc = '[
{ "foo":
{"bar":"foo",
"bar": {
["foo":"bar", "foo":"bar"]
}
}
}
],
"foo":"bar","foo":"bar"'
puts YourFileParser.new.parse(doc)[1..-1].map{|value| value["value"]}.join(",")