2016-02-14 2 views
3

J'ai un fichier CSV mais le délimiteur est un point-virgule ; et chaque colonne est entourée de guillemets. Il y a aussi des occurrences de ; dans certaines valeurs telles que & amp;Analyse du fichier du délimiteur de semi-côlon

J'utilise TextFieldParser pour analyser le fichier. Ce sont les données de l'échantillon:

"A001";"RT:This is a tweet"; "http://www.whatever.com/test/module & amp;one"

Pour l'exemple ci-dessus, je reçois plusieurs colonnes/champs que ce que je devrais obtenir.

Field[0] = "A001"
Field[1] = "RT:This is a tweet"
Field[2] = "http://www.whatever.com/test/module&amp"
Field[3] = "one"

Ceci est mon code. Quels changements doivent être faits pour gérer un tel scénario?

using (var parser = new TextFieldParser(fileName)) 
      { 
       parser.TextFieldType = FieldType.Delimited; 
       parser.SetDelimiters(";"); 
       parser.TrimWhiteSpace = true; 
       parser.HasFieldsEnclosedInQuotes = false; 

       int rowIndex = 0; 
       PropertyInfo[] properties = typeof(TwitterData).GetProperties(); 
       while (parser.PeekChars(1) != null) 
       { 
        var cleanFieldRowCells = parser.ReadFields().Select(
         f => f.Trim(new[] { ' ', '"' })); 

        var twitter = new TwitterData(); 
        int index = 0; 
        foreach (string c in cleanFieldRowCells) 
        { 
          string str = c; 

          if (properties[index].PropertyType == typeof(DateTime)) 
          { 
           string twitterDateTemplate = "ddd MMM dd HH:mm:ss +ffff yyyy"; 
           DateTime createdAt = DateTime.ParseExact(str, twitterDateTemplate, new System.Globalization.CultureInfo("en-AU")); 
           properties[index].SetValue(twitter, createdAt); 
          } 
          else 
          { 
           properties[index].SetValue(twitter, str); 
          } 

         index++; 
        } 
       } 

-Alan-

+0

Avez-vous essayé la mise 'HasFieldsEnclosedInQuotes' true? – kuujinbo

+0

Oui je l'ai fait mais pas différent –

+0

Essayez d'appeler System.Net.WebUtility.HtmlDecode() sur chaque ligne. Il va tourner '&' dans '&', ainsi que tout autre décodage. – kuujinbo

Répondre

2

En utilisant les deux chaînes d'échantillons que vous avez ci-dessus et définir la propriété HasFieldsEnclosedInQuotes à de véritables œuvres pour moi.

string LINES = @" 
    ""A001"";""RT:This is a tweet""; ""http://www.whatever.com/test/module&one"" 
    ""A001"";""RT: Test1 ; Test2"";""test.com""; 
"; 
using (var sr = new StringReader(LINES)) 
{ 
    using (var parser = new TextFieldParser(sr)) 
    { 
     parser.TextFieldType = FieldType.Delimited; 
     parser.SetDelimiters(";"); 
     parser.TrimWhiteSpace = true; 
     parser.HasFieldsEnclosedInQuotes = true; 

     while (parser.PeekChars(1) != null) 
     { 
      var cleanFieldRowCells = parser.ReadFields().Select(
       f => f.Trim(new[] { ' ', '"' })).ToArray(); 
      Console.WriteLine("New Line"); 
      for (int i = 0; i < cleanFieldRowCells.Length; ++i) 
      { 
       Console.WriteLine(
        "Field[{0}] = [{1}]", i, cleanFieldRowCells[i] 
       ); 
      } 
      Console.WriteLine("{0}", new string('=', 40)); 
     } 
    } 
} 

SORTIE:

New Line 
Field[0] = [A001] 
Field[1] = [RT:This is a tweet] 
Field[2] = [http://www.whatever.com/test/module&amp;one] 
======================================== 
New Line 
Field[0] = [A001] 
Field[1] = [RT: Test1 ; Test2] 
Field[2] = [test.com] 
Field[3] = [] 
======================================== 
+0

ce qui précède fonctionne bien comme il est. Cependant, si je copie les LINES dans un fichier et que je lis le contenu du fichier (File.ReadAllText), j'obtiens une exception ("La ligne 1 ne peut pas être analysée avec les délimiteurs actuels") –

+0

@AlanB - vous ne pouvez pas simplement copier ' LINES tel quel, parce que c'est une chaîne ** 'C# verbatim' **. C'est à dire. les doubles guillemets sont échappés. Au lieu de cela, le fichier texte [devrait ressembler à ceci] (https://raw.githubusercontent.com/kuujinbo/StackOverflow.RegularExpressions/master/_INPUT/TextFieldParseRegex.txt), et vous pouvez ensuite passer le chemin d'accès au fichier texte que vous fait dans votre exemple original, au lieu d'utiliser 'File.ReadAllText()'. [Jetez un oeil à la mise à jour] (https://github.com/kuujinbo/StackOverflow.RegularExpressions/blob/master/CSharp/TextFieldParseRegex.cs). – kuujinbo