Pyon's Diary
成る可くJIS X 0213:2004對應MSフォント(5.0)、IPAフォント(003.02)で御覽下さい
2006-02-23 舊 平成拾捌年睦月廿陸日 (木・曇) [長年日記]
Ruby で Excel 形式の CSV ファイルを讀込む。(其之貳)
(其之壹へ) 昨日の讀込部分を凾數として獨立させた。後で仕事場で參照出來る樣に此處に載せて置く。
引數は File オブジェクトとエンコーディング。エンコーディングの方は指定がなければ廣域變數 $KCODE の値を使用する。ブロック の指定がない場合は、二次元配列を返す。(2006-02-24 一部修正。)
def parse_csv(io, enc = $KCODE)
# check parameter
if (! io.kind_of?(File))
raise ArgumentError.new("'io' must be instance of File")
end
if (/\A(e|j|s|u)/im !~ enc)
raise ArgumentError.new("'enc' must be 'e', 'j', 's', or 'u'")
end
# pattern for parsing
tail = Regexp.new('(?:\r\n|[\r\n])?\Z', Regexp::MULTILINE, enc)
quoted = Regexp.new('\A"([^"]*(?:""[^"]*)*)",', Regexp::MULTILINE, enc)
unquoted = Regexp.new('\A([^,]*),', Regexp::MULTILINE, enc)
# parsing csv
rows = []
buffer = ""
io.each do |line|
# read until endo of row
next if ((buffer << line).count('"') % 2) != 0
buffer.sub!(tail, ',')
#
columns = []
while ! buffer.empty?
if quoted =~ buffer
buffer = $' || ""
columns << $~[1].gsub(/""/, '"')
elsif unquoted =~ buffer
buffer = $' || ""
columns << $~[1]
else
buffer = ""
end
end
#
if block_given?
yield(columns)
else
rows << columns
end
end
#
block_given? ? nil : rows
end
[ツッコミを入れる]
[]