FasterCSV:几个分隔符

我的Rails3应用程序解析用户上传的CSV文件。
可以预料,用户会上传以制表符分隔的AND逗号分隔文件。
我想支持两者。

我的代码:

input = CSV.read(uploaded_io.tempfile, { encoding: "UTF-8", :col_sep => "\t"}) 

问题:如何更改它以支持逗号?

FasterCSV的doc将col_sep描述为The String placed between each field. 所以:col_sep => ",\t"将无效。

注意:内部的所有数据都是整数或标识符,因此在内容(而不是分隔符)中使用\t或者\t的人的概率为零。 因此,在同一文件中使用两个不同的分隔符并不是我明确希望防止的。

解决方案1:

一种简单的方法是让用户通过下拉列表选择他们在CSV文件中使用的分隔符,然后在CSV.read()调用中设置该值。 但我想你想要它是自动的。 🙂

解决方案2:

您可以使用常规File.read()读入CSV文件的第一行,并通过匹配第一行对/,/然后对/\t/ …进行分析,具体取决于哪个RegExp匹配,您选择CSV.read()中的分隔符调用相应的(单个)分隔符。 然后,您相应地使用CSV.read(..., :col_sep => single_separator )读取文件。

但要注意:

首先,它看起来很漂亮和优雅,想要使用",\t"作为方法调用中的分隔符以允许两者 – 但请注意这将引入一个可能令人讨厌的错误!

如果一个CVS文件偶然或偶然地包含选项卡和逗号…那你怎么办? 两者分开? 你怎么能确定? 我认为这是一个错误,因为CSV分隔符在常规CSV文件中看起来不像这样“混合” – 它总是','"\t"

所以我认为你不应该使用",\t" – 这可能会导致巨大的问题,这可能是他们没有实现/允许col_sep选项接受RegExp的原因。

如果数据不包含转义引号等,只需在正则表达式上拆分即可。

 f = File.new("some_file.csv") res = f.readlines.map{|line| line.chomp.split(/[\t,]/)} f.close 

残酷的解决方案:

 require 'csv' csv= CSV.new("some_file") csv.instance_variable_set(:@col_sep, /[\t,]/)