FasterCSV: несколько разделителей - PullRequest
4 голосов
/ 20 октября 2011

Приложение My Rails3 анализирует загруженные пользователем файлы CSV.
Как и следовало ожидать, пользователи загружают файлы, разделенные табуляцией и запятыми.
Я хочу поддержать оба.

Мой код:

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

ВОПРОС: Как изменить его на поддержку запятых тоже?

Документ FasterCSV описывает col_sep как The String placed between each field., поэтому :col_sep => ",\t" не будет работать.

Примечание: все данные внутри являются целыми числами или идентификаторами, поэтому вероятность того, что кто-то использует \t или , в содержимом (не разделитель), равна нулю. Поэтому использование двух разных разделителей в одном и том же файле - это не то, что я прямо хочу предотвратить.

Ответы [ 3 ]

4 голосов
/ 20 октября 2011

Решение 1:

Один простой способ сделать это - дать пользователю выбрать из выпадающего списка, какой разделитель он использует в своем CSV-файле, а затем просто установить егозначение в вызове CSV.read().Но я думаю, вы хотите, чтобы это было автоматически.: -)

Решение 2:

Вы можете прочитать в первой строке CSV-файла обычную File.read() и проанализировать ее, сопоставив первую строку с/,/ и затем против /\t/ ... в зависимости от того, какой RegExp соответствует, вы выбираете разделитель в вызове CSV.read() соответствующего (одиночного) разделителя.Затем вы читаете в файле с помощью CSV.read(..., :col_sep => single_separator ) соответственно.

Но будьте осторожны:

Сначала выглядит красиво и элегантно, что вы хотите использовать ",\t" в качестве разделителяв вызове метода, чтобы разрешить и то и другое - но учтите, что это может привести к неприятной ошибке!

Если файл CVS будет содержать и вкладки, и запятые случайно или случайно ... что вы будете делать тогда?Отдельно на обоих?Как ты можешь быть уверен?Я думаю, что это было бы ошибкой, потому что разделители CSV не выглядят «смешанными», как это в обычных файлах CSV - это всегда либо ',' или "\t"

Так что я думаю, что вы не должны использовать1030 * - это может вызывать огромные проблемы, и это, вероятно, причина, по которой они не реализовали / не позволили опции col_sep принять RegExp.

0 голосов
/ 20 октября 2011

Брутальный раствор:

require 'csv'
csv= CSV.new("some_file")
csv.instance_variable_set(:@col_sep, /[\t,]/)
0 голосов
/ 20 октября 2011

Если данные не содержат экранирующих кавычек и т. Д., То просто деление на регулярное выражение сделает это.

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