Ruby通过字符串解析
我有一个如下所示的字符串,我必须删除第一个括号和最后一个括号之间的所有内容。所有投注都是关闭的,关于其中的内容(关于其他括号)。什么是最好的方法,谢谢。Ruby通过字符串解析
'[
{ "foo":
{"bar":"foo",
"bar": {
["foo":"bar", "foo":"bar"]
}
}
}
],
"foo":"bar","foo":"bar"'
结果:
',
"foo":"bar","foo":"bar"'
如果数据确实像她那样,你不会在年底有位的支架则:
s.gsub(/\[.*\]/m, '')
如果你想要多一点偏执狂,那么你可以看看],
后面跟着一个行尾:
s.gsub(/\[.*\],$/m, ',')
很难说没有数据格式的规格。
不错,观察得很好,实际上最后一点可能有括号。我必须找到第一个开放括号的相应的括号,并删除它们之间的内容。顺便说一句,这是JSON,但我不能把它当作哈希,因为顺序很重要。总疼痛。所以,这几乎可行,但如果我在最后有括号,该怎么办?谢谢! – dt1000
@ dt1000:但是你发布的问题不是JSON。您可能想用真实数据(或至少有效的假数据)更新您的问题。我认为修复JSON生产者产生明智的JSON(即,有序的东西在数组中)是不可能的? –
@ dt1000:另外,您究竟如何确定要删除的部分? –
在这里你去:
string.gsub(/\[.*\]/m, '')
您需要使用的M标记的。匹配换行符。 。*已经是贪婪的了,所以它会匹配任意数量的括号。
你需要多行模式:
str.gsub(/\[.*\]/m, '')
您可以使用类似Parslet写一个解析器。 这是我写的一个例子,基于从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语法为您的文档是无效的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(",")
您的示例数据似乎不是有效的JSON。它应该是?偏差是: - 最内层的数组使用对,所以它应该是一个对象。AND最外层的范围似乎是一个列表,但它包含[]和对“”:“”..所以它不是一个对象身体或阵列身体。 - 这是你的意图吗? –