Techioz Blog

RubyでCSVファイルの列区切り文字を検出するにはどうすればよいですか?

概要

取締役会のメンバーがアップロードした CSV ファイルが、カンマ区切り、セミコロン区切り、タブ区切りなどの一貫性のない形式のために正しく解析されないという問題がいくつかありました。通常、どの区切り文字が使用されているかさえわかりませんでした。 Excel / LibreOffice Calc では CSV にエクスポートするときに指定しないため使用されます。

解決策

この関数は、CSV に少なくとも 4 つの列があることを前提としています。ファイルの最初の行 (= 通常はヘッダーであり、余分なカンマや奇妙な文字が含まれる可能性は低い) で区切り文字と非区切り文字の交互を検索し、最も一般的な区切り文字を返します。

  def self.detect_separator(file)
    firstline = File.open(file, &:readline)
    if firstline
      separators = ",;\t|#"
      non_sep = "[^" + separators + "]+"
      sep = "([" + separators + "])"
      reg = Regexp.new(non_sep + sep + non_sep + sep + non_sep + sep + non_sep + sep)
      m = firstline.match(reg)
      if m 
        four_separators = m[1..-1].join('') # this line should have four separators but may have less if the data is less conclusive
        detected_separator = separators.split('').map {|x| [four_separators.count(x),x]}.max
        return detected_separator[1] if detected_separator
      end
    end
    nil
  end