在.NET中解析分隔的CSV

hac*_*ker 24 .net vb.net csv parsing

我有一个逗号分隔格式的文本文件,由"大多数字段分隔.我试图将其纳入我可以枚举的内容(例如,Generic Collection).我无法控制文件的输出方式以及它用于分隔符的字符.

在这种情况下,字段用逗号分隔,文本字段用"标记括起来.我"遇到的问题是某些字段中有引号(即8个托盘)并且意外地被拾取作为下一个字段.在数字字段的情况下,它们周围没有引号,但它们以+或 - 符号开头(描绘正/负数).

我在考虑一个RegEx,但我的技能并不是那么好,所以希望有人可以提出一些我可以尝试的想法.此文件中有大约19,000条记录,因此我尝试尽可能高效地执行此操作.以下是几行示例数据:

"00","000000112260   ","Pie Pumpkin                             ","RET","6.99 ","     ","ea ",+0000000006.99000
"00","000000304078   ","Pie Apple caramel                       ","RET","9.99 ","     ","ea ",+0000000009.99000
"00","StringValue here","8" Tray of Food                             ","RET","6.99 ","     ","ea ",-00000000005.3200
Run Code Online (Sandbox Code Playgroud)

还有更多的领域,但你可以得到图片....

我正在使用VB.NET,我有一个通用的List设置来接受数据.我已经尝试过使用CSVReader,它似乎运行良好,直到你达到第3个记录(在文本字段中引用).如果我能以某种方式让它来处理额外的引号,那么CSVReader选项将会很好用.

谢谢!

小智 76

我建议在.Net中查看TextFieldParserClass.你需要包括

Imports Microsoft.VisualBasic.FileIO.TextFieldParser
Run Code Online (Sandbox Code Playgroud)

这是一个快速示例:

        Dim afile As FileIO.TextFieldParser = New FileIO.TextFieldParser(FileName)
        Dim CurrentRecord As String() ' this array will hold each line of data
        afile.TextFieldType = FileIO.FieldType.Delimited
        afile.Delimiters = New String() {","}
        afile.HasFieldsEnclosedInQuotes = True

        ' parse the actual file
        Do While Not afile.EndOfData
            Try
                CurrentRecord = afile.ReadFields
            Catch ex As FileIO.MalformedLineException
                Stop
            End Try
        Loop
Run Code Online (Sandbox Code Playgroud)

  • +1,即使在C#中使用它感觉很脏. (8认同)
  • 仅供参考:TextFieldParser实现IDisposable,应该包含在"using"语句中或明确处理. (5认同)
  • 有没有人知道为什么这样的通用类会存在于VisualBasic命名空间中? (2认同)

Mid*_*one 11

试试这个网站. http://kbcsv.codeplex.com/

我已经找到了一个很好的实用工具,这是我找到并正常工作的最好的.不要浪费你的时间尝试其他东西,这是免费的,它的工作原理.


Mit*_*eat 7

这里:

Encoding fileEncoding = GetFileEncoding(csvFile);
// get rid of all doublequotes except those used as field delimiters
string fileContents = File.ReadAllText(csvFile, fileEncoding);
string fixedContents = Regex.Replace(fileContents, @"([^\^,\r\n])""([^$,\r\n])", @"$1$2");
using (CsvReader csv =
       new CsvReader(new StringReader(fixedContents), true))
{
       // ... parse the CSV
Run Code Online (Sandbox Code Playgroud)


sto*_*one 7

正如此链接所说... 不要滚动自己的CSV解析器!

使用TextFieldParser作为Avi建议.Microsoft已经为您完成了此操作.如果您最终编写了一个,并且发现其中有错误,请考虑替换它而不是修复错误.我最近做了那件事,它为我节省了很多时间.


Jos*_*ose 5

您可以尝试给CsvHelper(我维护的库),它可以通过NuGet获得.它遵循CSV 的RFC 4180标准.它将能够处理字段内的任何内容,包括逗号,引号和新行.

CsvHelper易于使用,但它也很容易配置它以使用许多不同类型的分隔文件.

CsvReader csv = new CsvReader( streamToFile );
IEnumerable<MyObject> myObjects = csv.GetRecords<MyObject>();
Run Code Online (Sandbox Code Playgroud)

如果要在较低级别读取CSV文件,可以直接使用解析器,它将每行作为字符串数组返回.

var parser = new CsvParser( myTextReader );
while( true )
{
    string[] line = parser.ReadLine();
    if( line == null )
    {
        break;
    }
}
Run Code Online (Sandbox Code Playgroud)