2010-12-10 59 views

回答

92

Ruby CSV庫允許您指定字段分隔符。 Ruby 1.9使用FasterCSV。像這樣的東西可以工作:

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

請注意,如果任何製表符分隔的值包含雙引號,則此方法將失敗。另一個答案中的StrictTsv建議更強大。 – 2016-11-01 01:49:02

23

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

+0

請在答案中加入代碼片段,*不要*在外部要點中。這個要點現在似乎已經下降了,這是一個真正的恥辱。 – 2015-02-01 19:26:23

0

找到我喜歡mmmries答案。但是,我討厭紅寶石從分裂結束時消除任何空值的方式。它也沒有在行結束時剝離換行符。

此外,我有一個文件與一個字段中的潛在換行符。所以,我改寫了他的「解析」,如下所示:

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 

這樣可以將在必要時得到了全系列的任何數據線,並始終返回全套資料(不包括潛在的零項在年底)。

相關問題