CSV Options d'Analyse .NET

Je suis à la recherche de mon délimité par fichier (par exemple, CSV, tab séparées, etc.) options d'analyse basée sur MS pile en général, et de .net en particulier. La seule technologie, je suis l'exclusion est SSIS, parce que je sais déjà qu'il ne sera pas répondre à mes besoins.

Donc mes options semblent être les suivants:

  1. Regex.Split
  2. TextFieldParser
  3. OLEDB CSV Analyseur

J'ai deux critères je dois le rencontrer. Tout d'abord, étant donné le fichier suivant qui contient deux logiques lignes de données (et de cinq lignes physiques au total):

101, Bob, "Keeps his house ""clean"".
Needs to work on laundry."
102, Amy, "Brilliant.
Driven.
Diligent."

L'analyse des résultats doit donner deux logiques "lignes", constitué de trois chaînes de caractères (ou de colonnes). La troisième rangée/colonne de chaîne doit conserver les retours à la ligne! Autrement dit, l'analyseur doit reconnaître quand les lignes sont "continuer" sur la prochaine ligne physique, en raison de la "ouverte" qualificateur de texte.

Le deuxième critère est que le séparateur et le délimiteur de texte doit être configurable par fichier. Voici deux cordes, prises à partir de différents fichiers, que je dois être en mesure d'analyser:

var first = @"""This"",""Is,A,Record"",""That """"Cannot"""", they say,"","""",,""be"",rightly,""parsed"",at all";
var second = @"~This~|~Is|A|Record~|~ThatCannot~|~be~|~parsed~|at all";

Une analyse correcte de la chaîne "premier" serait:

  • Ce
  • Est,Une,Enregistrement
  • Qui "Ne peut pas", disent-ils,
  • _
  • _
  • être
  • à juste titre,
  • analysé
  • à tous les

Le '_' signifie simplement que le vide a été capturé - je ne veux pas un littéral trait de soulignement à apparaître.

Une hypothèse importante peut être faite à propos de la plate-fichiers à analyser: il y aura un nombre fixe de colonnes par fichier.

Maintenant pour une plongée dans les options techniques.

REGEX

Tout d'abord, de nombreux intervenants commentaire que l'expression rationnelle "n'est pas le meilleur moyen" pour atteindre l'objectif. Je n'ai, toutefois, de trouver une intervenant qui a offert une excellente CSV regex:

var regex = @",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))";
var Regex.Split(first, regex).Dump();

Les résultats, appliqué à la chaîne "d'abord," sont tout à fait merveilleux:

  • "Ce"
  • "Est,Une,Dossier"
  • "Qui "Ne"peut pas"", disent-ils,"
  • ""
  • _
  • "être"
  • à juste titre,
  • "analysé"
  • à tous les

Ce serait bien si les citations ont été nettoyé, mais je peux facilement traiter avec cela comme un post-traitement à l'étape. Sinon, cette approche peut être utilisée pour analyser des exemples de chaînes de "première" et "seconde" si la regex est modifié pour tilde et les symboles de tuyau en conséquence. Excellent!

Mais le vrai problème concerne le multi-ligne critères. Avant une expression régulière peut être appliquée à une chaîne, je dois lire l'intégralité de l'logique de "ligne" à partir du fichier. Malheureusement, je ne sais pas combien de lignes physiques à lire pour compléter la logique de ligne, sauf si j'ai une regex /machine d'état.

Si cela devient une "poule et de l'œuf" problème. Ma meilleure option serait de lire l'intégralité du fichier en mémoire comme un géant de la chaîne, et de laisser les regex trier les multiples lignes (je n'ai pas vérifier si la regex pourrait gérer ça). Si j'ai un 10 gig fichier, cela pourrait être un peu précaire.

Sur pour l'option suivante.

TextFieldParser

Trois lignes de code, le problème avec cette option apparente:

var reader = new Microsoft.VisualBasic.FileIO.TextFieldParser(stream);
reader.Delimiters = new string[] { @"|" };
reader.HasFieldsEnclosedInQuotes = true;

Les Délimiteurs de configuration a l'air bon. Cependant, le "HasFieldsEnclosedInQuotes" est "game over". Je suis stupéfait que les délimiteurs sont arbitrairement configurable, mais en revanche je n'ai pas d'autre qualificatif d'autre option que de citations. Rappelez-vous, j'ai besoin de configurabilité sur le qualificateur de texte. Encore une fois, à moins que quelqu'un connait une TextFieldParser astuce de configuration, c'est game over.

OLEDB

Un collègue me dit que cette option a deux grands défauts. Tout d'abord, il est terrible de performance pour les grands (par exemple, 10 gig) des fichiers. Deuxième, donc je me suis dit, à ce qu'il devine de données les types de données d'entrée plutôt que de le laisser vous spécifiez. Pas bonne.

AIDER

Donc je voudrais savoir les faits que j'ai du mal (le cas échéant), et les autres options que j'ai manqué. Peut-être quelqu'un connaît un moyen de jury-rig TextFieldParser à utiliser l'arbitraire d'un délimiteur. Et peut-être OLEDB a résolu les domaines susmentionnés (ou peut-être ne les avait?).

Qu'en dites-vous?

Avez-vous essayé les options répertoriées dans le stackoverflow.com/questions/316649/csv-parsing ?
Je suis d'accord avec @Appleman1234, Filehelpers tout ce qu'il faut
Ne Filehelpers de répondre à vos exigences ?
double possible de la Lecture des fichiers CSV en C#

OriginalL'auteur Brent Arias | 2012-03-09