一尘不染

NET的CSV解析选项

c#

关闭。 此问题不符合堆栈溢出准则。它当前不接受答案。


想改善这个问题吗? 更新问题,使其成为Stack Overflow
的主题

5年前关闭。

我正在查看一般基于MS堆栈(特别是.net)的分隔文件(例如CSV,制表符分隔等)解析选项。我要排除的唯一技术是SSIS,因为我已经知道它不能满足我的需求。

所以我的选择似乎是:

  1. 正则表达式
  2. TextFieldParser
  3. OLEDB CSV解析器

我必须满足两个条件。首先,给定以下文件,其中包含两个逻辑数据行(以及五个物理行):

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

解析的结果必须产生两个逻辑“行”,每个行由三个字符串(或列)组成。第三行/列字符串必须保留换行符!换句话说,由于“未封闭”文本限定符,解析器必须识别行何时“继续”到下一个物理行。

第二个条件是,每个文件的定界符和文本限定符必须是可配置的。这是我必须能够解析的来自不同文件的两个字符串:

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";

字符串“ first”的正确解析为:

  • 这个
  • 是,A,记录
  • 他们说,“不能”
  • _
  • _
  • 正确地
  • 解析
  • 完全没有

“ _”只是表示捕获了一个空白-我不希望出现文字下划线。

可以对要解析的平面文件做出一个重要假设:每个文件中的列数是固定的。

现在开始深入探讨技术选择。

正则表达式

首先,许多响应者评论说正则表达式“不是实现目标的最佳方法”。但是,我确实找到了提供出色CSV正则表达式评论者

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

应用于字符串“ first”的结果非常棒:

  • “这个”
  • “是,A,记录”
  • 他们说:“那“”不能“,”
  • _
  • “是”
  • 正确地
  • “解析”
  • 完全没有

如果清理引号会很好,但是我可以轻松地将其作为后处理步骤来处理。否则,此方法可用于解析样本字符串“ first”和“
second”,前提是正则表达式已相应地针对代字号和管道符号进行了修改。优秀的!

但是真正的问题与多行标准有关。在将正则表达式应用于字符串之前,我必须从文件中读取完整的逻辑“行”。不幸的是,除非拥有正则表达式/状态机,否则我不知道要读取多少物理行才能完成逻辑行。

因此,这成为一个“鸡与蛋”的问题。我最好的选择是将整个文件作为一个大字符串读入内存,并让正则表达式整理出多行(我没有检查上面的正则表达式是否可以处理)。如果我有一个10
gig的文件,这可能有点不稳定。

转到下一个选项。

TextFieldParser

三行代码将使此选项的问题显而易见:

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

Delimiters配置看起来不错。但是,“
HasFieldsEnclosedInQuotes”是“游戏结束”。我很震惊,定界符是可以任意配置的,但是相比之下,除了引号之外,我没有其他限定符选项。记住,我需要在文本限定符上具有可配置性。再说一次,除非有人知道TextFieldParser配置技巧,否则这一切就结束了。

OLEDB

一位同事告诉我,此选项有两个主要缺点。首先,它对大型文件(例如10
gig)的性能非常糟糕。其次,有人告诉我,它猜测输入数据的数据类型,而不是让您指定。不好。

帮帮我

因此,我想知道我错了的事实(如果有的话)以及我错过的其他选择。也许有人知道陪审团TextFieldParser使用任意定界符的方法。也许OLEDB已经解决了上述问题(或者也许从未解决过?)。

怎么说


阅读 196

收藏
2020-05-19

共1个答案

一尘不染

您是否尝试搜索已经存在的.NET
CSV解析器这个声称可以比OLEDB更快地处理多行记录。

2020-05-19