在Ruby中解析类似YAML的字符串的最佳方法是什么?

时间:2015-03-19 16:38:08

标签: ruby parsing yaml

我想解析identify -verbose(ImageMagick)的输出并将其作为哈希返回。输出看起来像这样:

  Format: JPEG (Joint Photographic Experts Group JFIF format)
  Mime type: image/jpeg
  Class: DirectClass
  Geometry: 200x276+0+0
  Resolution: 300x300
  Print size: 0.666667x0.92
  Units: PixelsPerInch
  Type: TrueColor
  Endianess: Undefined
  Colorspace: sRGB
  Depth: 8-bit
  Channel depth:
    red: 8-bit
    green: 8-bit
    blue: 8-bit
  Channel statistics:
    Pixels: 55200
    Red:
      min: 0 (0)
      max: 255 (1)
      mean: 53.5216 (0.209889)
      standard deviation: 50.4831 (0.197973)
      kurtosis: 1.76124
      skewness: 1.173

现在,我试图欺骗并使用YAML.load,但我得到了一个ParseError(这是一个很长的镜头,谁知道什么会导致它不是有效的YAML)。

那么,是否有一种优雅的方法可以将其解析为嵌套哈希?我想得到这样的输出:

{
  "Format" => "JPEG (Joint Photographic Experts Group JFIF format)",
  "Mime type" => "image/jpeg",
  "Class" => "DirectClass",
  ...
  "Channel depth" => {
    "red": "8-bit",
    "green": "8-bit",
    "blue": "8-bit",
  },
  ...
}

1 个答案:

答案 0 :(得分:1)

尝试将其转换为有效的YAML。事实上,此输出非常接近,如果您将行Image: <name>替换为Image:\n Name: <name>,则可以直接对其进行解析。

这是一个至少适用于你的例子的kludge:

require 'yaml'

def parse_image_magick_output(str)
  YAML::load(str.sub(/Image:\s*(.*?)$/m, "Image:\n  Name: \\1"))
end

pp parse_image_magick_output(get_im_output) # =>
# {"Image"=>
#   {"Name"=>"spec/fixtures/default.jpg",
#    "Format"=>"JPEG (Joint Photographic Experts Group JFIF format)",
#    "Mime type"=>"image/jpeg",
#    ...
#        "standard deviation"=>"50.4831 (0.197973)",
#        "kurtosis"=>1.76124,
#        "skewness"=>1.173}}}}

当然,不同的ImageMagick子命令可能会产生类似的非YAML输出(例如,不仅仅是Image / name的这种情况),所以不能保证这个例子一般都能正常工作(尽管你可能会在一般情况下匹配通过更多的努力来预测应该是什么YAML映射。