使用TextFieldParser解析CSV文本文件- MalformedLineException

7
我正在使用 C# TextFieldParser 类来开发 CSV 解析器。
我的 CSV 数据以 , 作为分隔符,并且字符串被 " 字符包围。
然而,有时数据行单元格中也可能有 ",这似乎会导致解析器抛出异常。

enter image description here

这是我目前的C#代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Microsoft.VisualBasic.FileIO;

namespace CSV_Parser
{
    class Program
    {
        static void Main(string[] args)
        {
            // Init
            string CSV_File = "test.csv";

            // Proceed If File Is Found
            if (File.Exists(CSV_File))
            {
                // Test
                Parse_CSV(CSV_File);
            }

            // Finished
            Console.WriteLine("Press any to exit ...");
            Console.ReadKey();
        }

        static void Parse_CSV(String Filename)
        {
            using (TextFieldParser parser = new TextFieldParser(Filename))
            {
                parser.TextFieldType = FieldType.Delimited;
                parser.SetDelimiters(",");
                parser.TrimWhiteSpace = true;
                while (!parser.EndOfData)
                {
                    string[] fieldRow = parser.ReadFields();
                    foreach (string fieldRowCell in fieldRow)
                    {
                        // todo
                    }
                }
            }
        }
    }
}

这是我的test.csv文件的内容:

" dummy test"s data",   b  ,  c  
d,e,f
gh,ij

如何处理行单元格数据中的 "


更新

根据 Tim Schmelter 的回答,我已将我的代码修改为以下内容:

static void Parse_CSV(String Filename)
{
    using (TextFieldParser parser = new TextFieldParser(Filename))
    {
        parser.TextFieldType = FieldType.Delimited;
        parser.SetDelimiters(",");
        parser.HasFieldsEnclosedInQuotes = false;
        parser.TrimWhiteSpace = true;
        while (parser.PeekChars(1) != null)
        {
            var cleanFieldRowCells = parser.ReadFields().Select(
                f => f.Trim(new[] { ' ', '"' }));

            Console.WriteLine(String.Join(" | ", cleanFieldRowCells));
        }
    }
}

似乎产生了以下结果(正确):

enter image description here

这是处理带引号的字符串最好的方法吗?


预处理文件以确保其格式正确。 - Sam Axe
你尝试过使用http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.fileio.textfieldparser.hasfieldsenclosedinquotes(v=vs.100).aspx吗? - Steve
如果尝试删除引号字符会发生什么?因此将HasFieldsEnclosedInQuotes设置为false - Tim Schmelter
@Steve - 这个标志不仅仅告诉解析器使用双引号括起来的字符串吗?我相信这是默认开启的。 - Latheesan
@TimSchmelter 这并不是真正的损坏。我们期望有这样的数据。例如,一个单元格可能有这样的数据:"11" Wide",我需要能够解析它... - Latheesan
2
@Latheesan:根据规范(RFC 4180),它已经损坏了:>> 如果使用双引号来包含字段,则出现在字段内部的双引号必须通过在其前面加上另一个双引号进行转义。 - jmoreno
1个回答

5
你能通过将HasFieldsEnclosedInQuotes设置为false来省略引用字符吗?
using (var parser = new TextFieldParser(@"Path"))
{
    parser.HasFieldsEnclosedInQuotes = false;
    parser.Delimiters = new[]{","};
    while(parser.PeekChars(1) != null)
    {
        string[] fields = parser.ReadFields();
    }
}

您可以手动删除引号:
var cleanFields = fields.Select(f => f.Trim(new[]{ ' ', '"' }));

谢谢Tim,使用你的想法,我稍微修改了代码以实现我想要的效果,见第一篇帖子更新。这是解析带引号字符串并保留引号的最佳方法吗? - Latheesan
1
至少这是我知道的唯一方法。我认为你的文件已经损坏,字段不应包含引号字符,否则应先清理该字段或使用其他引号字符。因此,此方法只是修复损坏文件的一种方式。 - Tim Schmelter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接