2011-10-20 5 views
4

L'application My Rails3 analyse les fichiers CSV téléchargés par l'utilisateur.
Comme on peut s'y attendre, les utilisateurs téléchargent des fichiers séparés par des virgules et séparés par des virgules.
Je veux soutenir les deux.FasterCSV: plusieurs séparateurs

Mon code:

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

QUESTION: Comment changer pour soutenir des virgules aussi?

La doc de FasterCSV décrit col_sep comme The String placed between each field. alors :col_sep => ",\t" ne fonctionnera pas.

Remarque: Toutes les données à l'intérieur sont des entiers ou des identifiants, donc la probabilité que quelqu'un utilise \t ou , dans le contenu (pas un délimiteur) est zéro. Donc, l'utilisation des deux différents délimiteurs dans le même fichier n'est pas quelque chose que je veux expressément empêcher.

Répondre

3

Solution 1:

Une façon simple de le faire est de laisser l'utilisateur sélectionner avec un menu déroulant qui utilisent separator ils dans leur fichier CSV, puis vous définissez simplement cette valeur dans le CSV.read() appel . Mais je suppose que tu le veux automatique. :-)

Solution 2:

Vous pouvez lire dans la première ligne du fichier CSV avec régulier File.read() et analyser en appariant la première ligne contre /,/ puis contre /\t/ ... selon ce que RegExp correspond, vous sélectionnez le séparateur dans l'appel CSV.read() au séparateur (unique) correspondant. Ensuite, vous lisez dans le fichier avec CSV.read(..., :col_sep => single_separator) en conséquence.

Mais méfiez-vous:

Au début, il est joli et élégant de vouloir utiliser ",\t" comme séparateur dans l'appel de méthode pour permettre à la fois - mais s'il vous plaît noter que ceci introduirait un possible bug méchant!

Si un fichier CVS contient à la fois des onglets et des virgules par hasard ou par hasard ... que faites-vous alors? Séparez les deux? Comment peux-tu être sûr? Je pense que ce serait une erreur, parce que les séparateurs CSV ne semblent pas « mixtes » comme celui-ci dans des fichiers CSV régulièrement - il est toujours soit ',' ou "\t"

Je pense que vous ne devriez pas utiliser ",\t" - qui pourraient être à l'origine d'énormes problèmes, et c'est probablement la raison pour laquelle ils n'ont pas implémenté/permis l'option col_sep pour accepter un RegExp.

+0

Voir la note que j'ajouté: les problèmes que vous évoquez sont compréhensibles, mais ne sont pas applicables ici. –

+0

OK, compris .. cela signifie que la solution 2 devrait fonctionner correctement .. correct?:) – Tilo

+0

+1 Oui, c'est une solution valable, merci! Avant d'accepter je vais attendre un jour ou deux, peut-être quelqu'un connaît une option FasterCSV oubliée qui le fait encore plus élégamment :-) –

0

Si les données ne contiennent pas de guillemets d'échappement et autres, il suffit de diviser une expression régulière.

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

solution Brutal:

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