Каков наилучший способ проанализировать файл с разделителями табуляции в Ruby?
каков наилучший (наиболее эффективный) способ анализа файла с разделителями табуляции в Ruby?
3 ответа:
библиотека CSV Ruby позволяет указать разделитель полей. Ruby 1.9 использует FasterCSV. Что-то вроде этого будет работать:
require "csv" parsed_file = CSV.read("path-to-file.csv", { :col_sep => "\t" })
правила для 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
Мне нравится ответ 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
это связывает любые строки, необходимые для получения полной строки данных, и всегда возвращает полный набор данных (без потенциальных нулевых записей в конце).