我有一个带有额外空格的字符串:
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
答案 0 :(得分:46)
@prices = CSV.parse(IO.read('prices.csv'), :headers=>true,
:header_converters=> lambda {|f| f.strip},
:converters=> lambda {|f| f ? f.strip : nil})
nil测试被添加到行而不是标题转换器,假设标题永远不是nil,而数据可能是,而nil没有strip方法。我真的很惊讶,AFAIK,:strip不是预定义的转换器!
答案 1 :(得分:3)
CSV支持headers和fields的“转换器”,可让您在传递到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的IO系统支持逐行“枚举”文件。一旦我的代码CSV.open
,文件就可读,each
读取每一行。整个文件不需要同时在内存中,这是不可扩展的(虽然在新机器上它变得更合理),并且,如果你测试,你会发现使用{{1读取文件非常快,可能与读取它一样快,解析它然后迭代解析的文件。
答案 2 :(得分:1)
您可以先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
编辑也剥离哈希键