避免Ruby JSON中的额外行.pretty_generate

slwdgvem  于 12个月前  发布在  Ruby
关注(0)|答案(4)|浏览(84)

我想生成这样的JSON格式:

{
   "a": {
       "b": 1
   },
   "c": [
       2
   ],
   "d": [],
   "e": {}
}

这很容易通过Python、JavaScript和Go中的标准JSON支持来实现。
在Ruby中,我很难得到准确的输出:

$ ~/.rbenv/versions/2.6.3/bin/irb 
irb(main):001:0> require 'json'
=> true
irb(main):002:0> puts JSON.pretty_generate({"a" => {"b" => 1}, "c" => [2], "d" => [], "e" => {}})
{
  "a": {
    "b": 1
  },
  "c": [
    2
  ],
  "d": [

  ],
  "e": {
  }
}
=> nil

问题:

  • 空对象渲染在两条线上。
  • 空数组呈现在三个(!)线。

有没有一种简单的方法来获得Ruby标准JSON支持,以呈现我想要的输出?

voase2hg

voase2hg1#

不可能使用Ruby的标准库JSON。JSON.pretty_generate使用具有预定义配置的JSON.generate

JSON::PRETTY_STATE_PROTOTYPE.to_hash
{:indent=>"  ",
 :space=>" ",
 :space_before=>"",
 :object_nl=>"\n",
 :array_nl=>"\n",
 :allow_nan=>false,
 :ascii_only=>false,
 :max_nesting=>100,
 :depth=>0,
 :buffer_initial_length=>1024}

您可以尝试:

puts JSON.pretty_generate(object, array_nl: '')
{
  "a": {
    "b": 1
  },
  "c": [    2  ],
  "d": [  ],
  "e": {
  }
}

我知道这不是您想要的,但是使用JSON.generate,您可以定制JSON输出生成。对于空对象/数组没有单独的配置。此外,它是用C实现的,所以猴子补丁也不会起作用。

rjjhvcjd

rjjhvcjd2#

我不确定这是否可能,但这里有一个正则表达式,可以实现你想要的。

structure = {
  "a" => {"b" => 1},
  "c" => [2],
  "d" => [],
  "e" => {}, 
  "f" => "string with [     ] and {       }"
}
json = JSON.pretty_generate(structure)

regex = /(?<content>"(?:[^\\"]|\\.)+")|(?<open>\{)\s+(?<close>\})|(?<open>\[)\s+(?<close>\])/m
puts json.gsub(regex, '\k<open>\k<content>\k<close>')
# {
#   "a": {
#     "b": 1
#   },
#   "c": [
#     2
#   ],
#   "d": [],
#   "e": {},
#   "f": "string with [     ] and {       }"
# }
#=> nil

使用的正则表达式从"[{字符开始匹配。
如果它从"开始匹配,它将匹配到字符串的末尾,忽略中间的所有内容。捕获content组中的整个字符串。openclose组将为空。当替换为gsub时,整个content组将被放回原处。这样做是为了在字符串上下文中否定{[字符。
如果它从[{开始匹配,它只允许空白字符,并查找匹配的]}。开始和结束字符将分别放置在openclose组中,中间的空白不会被捕获。content组将为空。只有openclose组将在替换时被放回(删除空白字符)。
这是比赛的图表。它不喜欢命名的组,所以我删除了它们来呈现图表。group #1对应contentgroup #2group #4对应opengroup #3group #5对应close

e0bqpujr

e0bqpujr3#

我发现neatjsongem对于生成JSON很有用,其中空数组/哈希在单行上呈现而不是3行。
您可以使用this online visual tool
查找临时选项**。
您可以使用gem install neatjson或将gem 'neatjson', '0.9'附加到Gemfile0.9是撰写本文时的最新版本,请随时调整)来安装它
然后这里是如何使用它获得预期的输出:

require 'json'
require 'neatjson'

structure = {
  "a" => {"b" => 1},
  "c" => [2],
  "d" => [],
  "e" => {}, 
  "f" => "string with [     ] and {       }"
}

json = JSON.neat_generate(
  structure,
  { 
    wrap:        true,
    indent:      '    ',
    after_colon: 1,
    after_comma: 1
  }
)
puts "#{json}\n"

我希望这有帮助,我没有找到一种方法来配置JSON.pretty_generate这样做,neatjson可以解决这个问题。它提供了无数的选项来微调JSON字符串。

kxe2p93d

kxe2p93d4#

由于Ruby的JSON格式是有限的,我通常使用jq在终端和Ruby中格式化JSON字符串。在使用jq和管道时,标识过滤器'.'是可选的,但我还是喜欢保留它。

require 'json'
require 'open3'

hash = {"a"=>{"b"=>1}, "c"=>[2], "d"=>[], "e"=>{}}
stdin_data = hash.to_json
formatted_json = Open3.capture2('jq .', stdin_data:)[0]
puts formatted_json

打印:

{
  "a": {
    "b": 1
  },
  "c": [
    2
  ],
  "d": [],
  "e": {}
}

相关问题