From: William James Date: 2006-12-27T06:15:09+09:00 Subject: Re: Parsing a CSV file having multiple records in RUBYp James Edward Gray II wrote: > On Dec 26, 2006, at 3:15 AM, come wrote: > > > Since your file has a header, you could write something like : > > Obviously I am biased, but I sure think FasterCSV makes this kind of > thing easier: > > >> require "rubygems" > => false > >> require "faster_csv" > => true > >> csv = < item,in_stock,reorder_limit > "Real ""Rubies""",10,5 > Pearls,100,20 > Snakes,2,5 > END_CSV > => "item,in_stock,reorder_limit\n"Real ""Rubies""",10,5\nPearls,100,20 > \nSnakes,2,5\n" > >> result = FCSV.parse(csv, :headers => true, :header_converters > => :symbol) > => # [# \"Rubies\""], [:in_stock, "10"], [:reorder_limit, "5"]]>, > # [:in_stock, "100"], [:reorder_limit, "20"]]>, # 0x6e4af0 @header_row=false, @row=[[:item, "Snakes"], [:in_stock, > "2"], [:reorder_limit, "5"]]>] > >> puts re > readline require__ result > readlines require_gem retry > redo require_gem_with_options return > remove_instance_variable rescue > require respond_to? > >> puts result.map { |row| row[:item] } > Real "Rubies" > Pearls > Snakes > => nil > >> result.each { |row| p row.to_hash } > {:in_stock=>"10", :reorder_limit=>"5", :item=>"Real \"Rubies\""} > {:in_stock=>"100", :reorder_limit=>"20", :item=>"Pearls"} > {:in_stock=>"2", :reorder_limit=>"5", :item=>"Snakes"} > => # [# \"Rubies\""], [:in_stock, "10"], [:reorder_limit, "5"]]>, > # [:in_stock, "100"], [:reorder_limit, "20"]]>, # 0x6e4af0 @header_row=false, @row=[[:item, "Snakes"], [:in_stock, > "2"], [:reorder_limit, "5"]]>] class String def csv (self + ",").scan( /("(?:[^"]+|"")*"|[^,]*),/).flatten. map{|s| s.gsub(/\A"|"\Z/,'').gsub(/""/,'"')} end end data = DATA.readlines.map{|s| s.chomp.csv} header = data.shift p header p data puts data.map{|a| header.zip(a).inject({}){|h,x| h.merge({x[0].to_sym,x[1]}) }}. each{|h| p h} __END__ item,in_stock,reorder_limit "Real ""Rubies""",10,5 Pearls,100,20 Snakes,2,5 --- output ----- ["item", "in_stock", "reorder_limit"] [["Real \"Rubies\"", "10", "5"], ["Pearls", "100", "20"], ["Snakes", "2", "5"]] {:in_stock=>"10", :reorder_limit=>"5", :item=>"Real \"Rubies\""} {:in_stock=>"100", :reorder_limit=>"20", :item=>"Pearls"} {:in_stock=>"2", :reorder_limit=>"5", :item=>"Snakes"}