Dupliqué possible: strong>
traiter avec des virgules dans un fichier CSV P>Je me suis écrit un analyseur CSV Cela fonctionne bien jusqu'à ce que je frappe cet enregistrement:
B002VECGTG, B002VECGTG, HAS_17131_SPACESHOOTER, "4 426", 0,04%, "4 832", 0,03%, 0%, 1,0,02%, 20,47 $, 1 code> Les échappés, dans "4,426" et dans "4,426" freinent mon analyseur. P>C'est ce que j'utilise pour analyser la ligne de texte: P>
char[] comma = { ',' }; string[] words = line.Split(comma);
3 Réponses :
Vous ne pouvez pas simplement vous séparer sur la virgule. Pour mettre en œuvre un analyseur approprié pour cette affaire, vous devez vous mettre en boucle dans la chaîne vous-même, en gardant une trace de si vous êtes à l'intérieur de citations ou non. Si vous êtes à l'intérieur d'une chaîne cité, vous devez continuer jusqu'à ce que vous trouviez une autre citation.
IEnumerable<string> LineSplitter(string line)
{
int fieldStart = 0;
for(int i = 0; i < line.Length; i++)
{
if(line[i] == ',')
{
yield return line.SubString(fieldStart, i - fieldStart);
fieldStart = i + 1;
}
if(line[i] == '"')
for(i++; line[i] != '"'; i++) {}
}
}
Cette méthode aime couper les mots.
J'ai soumis une modification pour l'erreur hors-tête dans la sous-chaîne et les accolades frisées manquantes sur la seconde en boucle. En outre, cela ne supprima pas les citations des champs cités et a un comportement différent de Split lorsqu'il est appelé ""
Cet exemple tombe le dernier article de la liste.
IEnumerable
Je suggère d'utiliser un analyseur CSV au lieu d'essayer d'analyser vous-même. p>
Il y a des nuances à analyser correctement CSV, comme vous l'avez déjà découvert. P>
Il existe de nombreux tiers (et plusieurs d'entre eux sont gratuits), et même une intégrée à l'espace de noms de base visual - le TextfieldParser code> dans le Microsoft.visalbasic.fileio Code> Espace de noms. P>
+1 pour le TextFieldParser Code> - Pourquoi est-il caché dans l'espace de noms VB?
@Anders - bonne question ... c'est une classe vraiment utile. Cependant, pour les grands fichiers CSV, il est apparemment lent.
Aimez le TextfieldParser code> ici aussi! Et également pertinent pour cette réponse à l'utilisation d'un utilitaire tiers, consultez la bibliothèque FichierHelPers chez FileHelPers.com (Licences LGPL) pour quelque chose non seulement très facile à utiliser, mais aussi comme un excellent exemple d'étudier et d'apprendre si vous le souhaitez ...
Il est possible d'utiliser une regex:
List<List<String>> rows = new List<List<String>>();
MatchCollection matches = Regex.Matches(input, @"^(?:(?:\s*""(?<value>[^""]*)""\s*|(?<value>[^,]*)),)*?(?:\s*""(?>value>[^""]*)""\s*|(?<value>[^,]*))$", RegexOptions.Multiline);
foreach(Match row in matches)
{
List<String> values = new List<String>();
foreach(Capture value in row.Groups["value"].Captures)
{
values.Add(value.Value);
}
rows.Add(values);
}
@ KD7 Cette solution utilise une bibliothèque pour analyser le fichier, ici, j'essaie de le faire avec Split.