Printing printing JSON in Ruby
What is the best way to pretty print JSON in Ruby with smart line wrapping , the way the "json" output formatter in underscore-cli handles it?
For instance, a regular JSON pretty printer would output:
{
"a": [
"b",
"c"
],
"d": {
"e": "f"
},
"g": [
"some longer string"
]
}
But I'm looking for a configurable pretty printer in Ruby that, like underscore-cli, notices that small structures make for pointlessly short lines, and so outputs something like this:
{
"a": [ "b", "c" ],
"d": { "e": "f" },
"g": [ "some longer string" ]
}
I've played around with the options available in JSON.generate()
(space, space_before, etc.), to no avail.
I'm writing a script which generates multiple JSON files intended to be reasonably comprehensible by humans (should the need arise) --- I can't expect underscore to be available everywhere so I can't (and ugh, wouldn't want to) just pipe the output through underscore, but the default JSON.pretty_generate()
outputs files which are far less readable with around three times as many lines as underscore (2,200 lines vs 750).
Ruby 2.0.0p481.
看起来neatjson会做我想做的事。
If your requirements are minimal you can play around with JSON#generate
opts to avoid using extra gems. Though I completely agree neatjson makes it cleaner.
A quick example:
a = {"a"=>["b", "c"], "d"=>{"e"=>"f"}, "g"=>["some longer string"]}
puts JSON.pretty_generate(a, array_nl:'')
#{
# "a": [ "b", "c" ],
# "d": {
# "e": "f"
# },
# "g": [ "some longer string" ]
#}
As soon as you just want to do the only thing, I would go with simple gsubbing (it is safe here):
▶ # ⇓ ldelim ⇓ not nest ⇓ cnt ⇓ rdelim
▶ puts JSON.pretty_generate(a).gsub(/(?<=[|{)[^[{]}]{,30}(?=]|})/m) do |m|
m.gsub(/s+/, ' ').strip
end
#⇒ {
# "a": ["b", "c"],
# "d": {"e": "f"},
# "g": ["some longer string"]
# }
It is configurable for the length of allowed “inlines” (30 in the example above) and ready to print output as you want (to surround inlines with spaces, just update the return value in block, given to gsub
.)
下一篇: 在Ruby中打印打印JSON