在Ruby中解析制表符分隔文件的最佳方法是什么?

时间:2010-12-10 01:14:11

标签: ruby tsv

在Ruby中解析制表符分隔文件的最佳(最有效)方法是什么?

4 个答案:

答案 0 :(得分:106)

Ruby CSV库允许您指定字段分隔符。 Ruby 1.9使用FasterCSV。像这样的东西会起作用:

require "csv"
parsed_file = CSV.read("path-to-file.csv", { :col_sep => "\t" })

答案 1 :(得分:30)

TSV的规则实际上与CSV略有不同。主要区别在于CSV具有在字段内粘贴逗号然后在字段内使用引号字符和转义引号的规定。我写了一个简单的例子来说明简单的响应是如何失败的:

require 'csv'
line = 'boogie\ttime\tis "now"'
begin
  line = CSV.parse_line(line, col_sep: "\t")
  puts "parsed correctly"
rescue CSV::MalformedCSVError
  puts "failed to parse line"
end

begin
  line = CSV.parse_line(line, col_sep: "\t", quote_char: "Ƃ")
  puts "parsed correctly with random quote char"
rescue CSV::MalformedCSVError
  puts "failed to parse line with random quote char"
end

#Output:
# failed to parse line
# parsed correctly with random quote char

如果你想使用CSV库你可以使用一个随机引用字符,你不希望看到你的文件(示例显示这个),但你也可以使用更简单的方法,如下面显示的StrictTsv类在不必担心现场报价的情况下获得相同的效果。

# The main parse method is mostly borrowed from a tweet by @JEG2
class StrictTsv
  attr_reader :filepath
  def initialize(filepath)
    @filepath = filepath
  end

  def parse
    open(filepath) do |f|
      headers = f.gets.strip.split("\t")
      f.each do |line|
        fields = Hash[headers.zip(line.split("\t"))]
        yield fields
      end
    end
  end
end

# Example Usage
tsv = Vendor::StrictTsv.new("your_file.tsv")
tsv.parse do |row|
  puts row['named field']
end

使用CSV库或更严格的选择取决于谁向您发送文件以及他们是否期望遵守严格的TSV标准。

有关TSV标准的详细信息,请访问http://en.wikipedia.org/wiki/Tab-separated_values

答案 2 :(得分:0)

我喜欢mmmries的回答。但是,我讨厌ruby从分裂结束时剥离任何空值的方式。它也不会在行尾删除换行符。

另外,我在一个字段中有一个潜在换行符的文件。所以,我重写了他的'解析'如下:

def parse
  open(filepath) do |f|
    headers = f.gets.strip.split("\t")
    f.each do |line|
      myline=line
      while myline.scan(/\t/).count != headers.count-1
        myline+=f.gets
      end
      fields = Hash[headers.zip(myline.chomp.split("\t",headers.count))]
      yield fields
    end
  end
end

这会根据需要连接所有行以获取完整的数据行,并始终返回完整的数据集(最后没有潜在的nil条目)。

答案 3 :(得分:0)

实际上有两种不同的TSV文件。

  1. TSV文件,实际上是CSV文件,分隔符设置为Tab。这是您在例如将Excel电子表格另存为“ UTF-16 Unicode文本”。这样的文件使用CSV引用规则,这意味着只要使用引号将字段包含制表符和换行符,并且文字双引号将被写入两次。正确解析所有内容的最简单方法是使用csv gem:

    use 'csv'
    parsed = CSV.read("file.tsv", col_sep: "\t")
    
  2. TSV文件符合IANA standard。不允许将制表符和换行符作为字段值,并且也没有引用。这是您在例如选择整个Excel电子表格并将其粘贴到文本文件中(请注意:如果某些单元格确实包含制表符或换行符,它将被弄乱)。可以使用简单的line.rstrip.split("\t", -1)轻松地逐行分析此类TSV文件(请注意-1,可防止split删除空的尾随字段)。如果要使用csv gem,只需将quote_char设置为nil

    use 'csv'
    parsed = CSV.read("file.tsv", col_sep: "\t", quote_char: nil)