Meilleure façon de gérer les fichiers délimités

16

Donc, généralement, un fichier CSV utilise une virgule et le caractère de retour comme ses délimiteurs de champ et de ligne.

Cela pose des problèmes évidents avec le texte qui peut contenir ces deux caractères.

De toute évidence, il existe des options (les échapper), mais comment les gens gèrent-ils cela? Utilisez des personnages différents - pipes ou tildas? Leur échapper? Ne pas utiliser de fichiers délimités, après tout, c'est 2010 et nous avons maintenant XML?

Vous cherchez au moins un effort pour une chance décente de ne pas voir de problèmes.

(Juste pour être clair, c'est une question par curiosité plutôt que quelque chose de plus solide - c'est quelque chose que j'ai rencontré maintes et maintes fois en jouant avec les données, je l'ai toujours contourné mais cela semble normalement un peu, eh bien, sale, et se demande quelle a été l'expérience des autres).

Jon Hopkins
la source
Réfléchissez bien à l'utilisation de CSV - c'est agréable et facile à gérer (voir les réponses pour les règles d'échappement communes), mais ce n'est pas aussi interopérable qu'il devrait l'être - si vous communiquez simplement avec vos propres programmes, c'est bien, mais si vous vouloir importer ailleurs, cela devient un peu étrange car différents programmes obéissent à des règles d'échappement différentes.
Michael Kohne
@Michael - Absolument. Le problème est cependant qu'il est si omniprésent que vous arriverez presque toujours à des moments où c'est une option très tentante, et dans le cas de nombreux systèmes plus anciens, c'est la seule option.
Jon Hopkins
Des bibliothèques matures existent dans de nombreuses langues (certainement les plus courantes) pour lire et écrire des fichiers délimités par des caractères. Ils géreront la plupart des situations. Écrire son propre analyseur CSV semble être une sorte d'anti-modèle courant.
quentin-star du

Réponses:

13

Selon Wikipedia :

Les champs avec des virgules incorporées doivent être placés entre guillemets doubles.

Et en plus:

Les champs avec des caractères de guillemet double incorporés doivent être placés entre des caractères de guillemet double et chacun des caractères de guillemet double incorporés doit être représenté par une paire de caractères de guillemet double.

Je ne sais pas qui a inventé cela, mais cela montre effectivement que finalement vous devez vous échapper. C'est la seule solution solide. Tout le reste n'est que du ruban adhésif sur le ruban adhésif: peut-être que ça marche pour le moment, mais vous finirez par tomber sur un cas où vous avez besoin d'une exception à l'exception d'une exception, et cela ne prend pas longtemps avant que votre boule de règles est bien plus complexe qu’une simple solution de caractère d’évasion.

Il semble que les créateurs CSV aient d'abord essayé d'éviter de s'échapper des virgules en proposant une syntaxe spéciale entre guillemets doubles, ce qui permettait d'enregistrer des virgules, mais ensuite quelqu'un a également voulu enregistrer les caractères entre guillemets doubles, ils ont donc dû s'échapper à ce stade - en utilisant drôlement guillemet double comme caractère d'échappement. S'ils avaient décidé de s'échapper correctement en premier lieu, la syntaxe serait plus simple maintenant.

Joonas Pulakka
la source
3
Ce qui devrait être et ce qui est .. diffère souvent :)
Tim Post
Je pense que la solution est tout à fait correcte. Pour les données simples, CSV fonctionne très bien, pour les données complexes, alors la citation est nécessaire, et s'échappe "avec" "des traces vers BASIC.
Ernelli
1
@Ernelli: Maintenant que j'y pense davantage, cela peut en fait être un compromis raisonnable entre la lisibilité humaine et la simplicité. Le problème qui s'échappe est qu'il semble laid pour les humains , même s'il est trivial pour l' ordinateur d'analyser. Ainsi, la réservation des échappements pour de rares cas uniquement ("champs avec des guillemets intégrés") produit une sortie qui semble généralement assez lisible par l'homme. C'est une bonne solution, en supposant que les virgules dans les noms de champ sont plus fréquemment utilisées que les guillemets doubles dans les noms de champ.
Joonas Pulakka
2

Je suppose que vous avez quelque chose comme ça:

Foo,Baz,,,"Foo,Baz"

Si les chaînes qui contiennent le délimiteur ne sont pas entre guillemets ou échappées, vous n'avez pas de véritable moyen fiable d'analyser le fichier.

Vous pouvez cependant examiner les données pour analyser et tirer des conclusions comme:

  • Les flottants séparés par des virgules doivent être traités comme une chaîne
  • Si la ligne avant ou après celle-ci contient moins de délimiteurs, ignorez l'analyse de cette ligne et enregistrez-la
  • Traitez comme "

Vous devez écrire un analyseur pour gérer des choses comme ça, mais cela ne doit pas être compliqué.

D'après mon expérience, l'importation de vidages massifs à partir de quelque chose comme Excel se traduit toujours par avoir à revenir en arrière et à passer en revue certaines bizarreries. Votre défi est de donner à votre programme juste assez de bon sens concernant les données afin qu'il ne fasse pas un insert fou. Ensuite, examinez ce qui a été enregistré et lavez / rincez / répétez.

Une fois, j'ai géré une FAQ interne pour une petite entreprise qui utilisait tous les postes de travail Ubuntu. Une partie de la FAQ a donné des «raccourcis shell», et il m'est venu délimité par des tuyaux. Eh bien, les réponses étaient également généralement délimitées par des tuyaux (c.-à-d. Grep foo | quelque chose) et non citées ou échappées. Je ressens cette douleur :)

Tim Post
la source
2

Rien de mal avec CSV jusqu'à un certain point

CSV fonctionne bien pour les données définies de manière rigide qui ne changeront probablement pas de format et ne surprendront pas beaucoup l'analyseur destinataire.

Voici une liste pratique des gros accrochages:

  1. Échappement de "" s dans "" s (le champ contient un délimiteur de champ)
  2. "" s contenant des CRLF (le champ contient un délimiteur de ligne)
  3. Unicode (le format de texte sous-jacent peut être insuffisant)
  4. Terminateurs de ligne différents pour différents systèmes d'exploitation (est CR ou CRLF ou LF ou NUL?)
  5. Commentaires en ligne (ligne préfixée par #, //, -,; etc)
  6. Gestion des versions (la dernière version du fichier contient plus ou moins de champs)
  7. Différencier les données NULL et vides (, "", est vide mais ,, est nul?)

Vous pouvez aborder cela avec un en-tête de métadonnées qui décrit comment les champs doivent être analysés, mais vous pouvez également utiliser XML. C'est à cause de ce genre de désordre CSV de forme libre qu'il a été inventé. L'approche XML semble tout simplement trop lourde pour ce qui pourrait, à première vue, être un problème simple.

Une alternative populaire est la stratégie de "délimiteur de caractères étranges". Cela permet de contourner la plupart des problèmes d'échappement ci-dessus, car vous utilisez quelque chose comme un | (canal) pour la délimitation des champs et un CRLF pour la fin de l'enregistrement. Cela ne résout pas le problème des champs multi-lignes (sauf si vous utilisez un compteur de champs) mais vous obtenez des lignes bien formatées pour les humains.

Dans l'ensemble, si vous cherchez simplement un moyen simple de gérer ce type de fichier, dans le monde Java, vous pouvez simplement lancer OpenCSV . De cette façon, vous résumez tous les problèmes dans un cadre établi.

Gary Rowe
la source
2

CSV est toujours un format valide dans de nombreuses situations, d'autant plus qu'il doit toujours être le moyen le plus simple pour un client d'écrire des données qui doivent être importées dans votre application. Peu de nos clients aiment traiter avec XML, peut-être parce qu'il est très bavard et a tous ces supports angulaires "effrayants". Il est tellement plus simple pour eux d'enrouler leur cerveau autour d'une simple liste d'éléments séparés par un caractère convenu, et également d'accord que le même caractère ne sera pas autorisé dans le contenu d'un champ.

Cela dit, vous devez toujours gérer correctement l'entrée et vérifier les situations où ils utilisent des caractères non valides. J'ai commencé à utiliser FileHelpers pour mes besoins d'analyse CSV.

Dave
la source
1

je m'en tiens habituellement à la norme et leur échappe. dans la plupart des langages de programmation, il existe un bon support intégré ou une bonne bibliothèque disponible.

cela dépend de la situation quel format sera utilisé et CSV est un format raisonnable pour échanger des structures de format de données simples.

Salandur
la source
0

Oubliez CSV, utilisez JSON . Facile à écrire, facile à analyser. XML est donc 2005 .

user281377
la source
6
et a le même problème lorsque vous souhaitez utiliser un personnage qui fait partie du format JSON (comme {ou,)
Salandur
Salandur: Pas du tout! Il y a des règles précises pour s'échapper! Mais {et, n'a même pas besoin d'être échappé, car à l'intérieur sont des cordes, elles ne sont pas ambiguës!
user281377
1
Bien et bien, mais je ne me souviens pas qu'Excel ait une fonction "Exporter vers JSON" :) Il y a des moments où vous devez analyser des choses étranges, ne serait-ce que pour les mettre dans un format plus agréable.
Tim Post
1
Et JSON est tellement génial pour faire circuler un million d'objets de la même forme. Oh, attendez.
Frank Shearar
1
JSON n'apporte aucune amélioration par rapport à CSV en ce qui concerne cette question et manque fondamentalement d'interopérabilité avec de nombreuses applications (comme cela a été mentionné, ne peut pas importer ou exporter à partir d'Office, de bases de données SQL, etc.). JSON est idéal pour les opérations internes légères côté client, mais XML est bien meilleur pour le transfert de données entre applications.
Dan Diplo
0

Habituellement, ce que je me retrouve à obtenir est un TSV (valeurs séparées par des tabulations) plutôt qu'un fichier CSV, tirez le fichier dans Emacs et voyez lequel des quelques caractères inhabituels qu'il n'utilise JAMAIS ($ est généralement un bon choix ici), puis je convertis tous les onglets en $.

De là, on peut dire à GNU AWK d'utiliser $ comme séparateur de champ, et Bob est votre oncle.

John R. Strohm
la source