18

我有一个带有额外空格的字符串:

First,Last,Email  ,Mobile Phone ,Company,Title  ,Street,City,State,Zip,Country, Birthday,Gender ,Contact Type

我想解析这一行并删除空格。

我的代码如下所示:

namespace :db do
task :populate_contacts_csv => :environment do

require 'csv'

csv_text = File.read('file_upload_example.csv')
  csv = CSV.parse(csv_text, :headers => true)
    csv.each do |row|
      puts "First Name: #{row['First']} \nLast Name: #{row['Last']} \nEmail: #{row['Email']}"
    end
  end
end
4

3 回答 3

63
@prices = CSV.parse(IO.read('prices.csv'), :headers=>true, 
   :header_converters=> lambda {|f| f.strip},
   :converters=> lambda {|f| f ? f.strip : nil})

The nil test is added to the row but not header converters assuming that the headers are never nil, while the data might be, and nil doesn't have a strip method. I'm really surprised that, AFAIK, :strip is not a pre-defined converter!

于 2013-04-07T08:44:35.080 回答
3

你可以strip先散列:

csv.each do |unstriped_row|
  row = {}
  unstriped_row.each{|k, v| row[k.strip] = v.strip}
  puts "First Name: #{row['First']} \nLast Name: #{row['Last']} \nEmail: #{row['Email']}"
end

编辑也剥离散列键

于 2013-01-21T16:06:36.697 回答
3

CSV 支持headersfields的“转换器” ,它可以让您在数据传递到each循环之前进入数据。

编写示例 CSV 文件:

csv = "First,Last,Email  ,Mobile Phone ,Company,Title  ,Street,City,State,Zip,Country, Birthday,Gender ,Contact Type
first,last,email  ,mobile phone ,company,title  ,street,city,state,zip,country, birthday,gender ,contact type
"
File.write('file_upload_example.csv', csv)

这是我的做法:

require 'csv'
csv = CSV.open('file_upload_example.csv', :headers => true)
[:convert, :header_convert].each { |c| csv.send(c) { |f| f.strip } }

csv.each do |row|
  puts "First Name: #{row['First']} \nLast Name: #{row['Last']} \nEmail: #{row['Email']}"
end

哪个输出:

First Name: 'first'
Last Name: 'last'
Email: 'email'

当从文件中读取每个标题和每个字段时,转换器只需从每个标题和每个字段中去除前导和尾随空格。

此外,作为编程设计选择,不要使用以下方法将文件读入内存:

csv_text = File.read('file_upload_example.csv')

然后解析它:

csv = CSV.parse(csv_text, :headers => true)

然后循环它:

csv.each do |row|

Ruby's IO system supports "enumerating" over a file, line by line. Once my code does CSV.open the file is readable and the each reads each line. The entire file doesn't need to be in memory at once, which isn't scalable (though on new machines it's becoming a lot more reasonable), and, if you test, you'll find that reading a file using each is extremely fast, probably equally fast as reading it, parsing it then iterating over the parsed file.

于 2013-01-21T17:14:58.930 回答