c# - .NET 的 CSV 解析选项

标签 c# .net parsing

关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。












想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。

6年前关闭。




Improve this question




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

所以我的选择似乎是:

  • Regex.Split
  • TextFieldParser
  • OLEDB CSV Parser

  • 我必须满足两个标准。首先,给定以下文件,其中包含两个逻辑数据行(总共五个物理行):
    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,记录
  • 他们说,“不能”,
  • _
  • _
  • 正确
  • 解析
  • 完全

  • '_' 仅表示捕获了一个空白 - 我不希望出现文字下划线。

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

    现在深入了解技术选项。

    正则表达式

    首先,许多响应者评论正则表达式“不是实现目标的最佳方式”。然而,我确实找到了一个 commenter who offered an excellent CSV regex :
    var regex = @",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))";
    var Regex.Split(first, regex).Dump();
    

    应用于字符串“first”的结果非常棒:
  • “这个”
  • “是,A,记录”
  • “那个“不能”,他们说,“
  • ""
  • _
  • "is"
  • 正确
  • “解析”
  • 完全

  • 如果引号被清理干净会很好,但我可以轻松地将其作为后处理步骤处理。否则,此方法可用于解析示例字符串“first”和“second”,前提是相应地针对波浪号和管道符号修改了正则表达式。优秀!

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

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

    进入下一个选项。

    文本字段解析器

    三行代码将使此选项的问题显而易见:
    var reader = new Microsoft.VisualBasic.FileIO.TextFieldParser(stream);
    reader.Delimiters = new string[] { @"|" };
    reader.HasFieldsEnclosedInQuotes = true;
    

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

    有机发光二极管

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

    帮助

    所以我想知道我错了的事实(如果有的话),以及我错过的其他选项。也许有人知道一种方法可以让 TextFieldParser 使用任意分隔符。也许 OLEDB 已经解决了上述问题(或者也许从未解决过这些问题?)。

    你们怎么说?

    最佳答案

    您是否尝试搜索已经存在的 .NET CSV parser ? This one声称处理多行记录的速度比 OLEDB 快得多。

    关于c# - .NET 的 CSV 解析选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9642055/

    相关文章:

    java - ANTLR - 如何使用生成的 AST 树?

    java - 在一台机器上获取 JDOMException 但相同的 xml 在另一台机器上工作正常

    java - 用于解析 markdown 的 Commonmarks 库 : how to parse three ticks

    c# - 从 UWP XAML 中的 HyperlinkBut​​ton 中删除下划线

    c# - 在具有相同终结点名称的不同用户 session 中运行的 net pipe WCF 服务

    .net - ASP.NET 中文本框的自动完成搜索组件

    c# - 关闭父对话框时关闭子对话框

    c# - 如何为 WPF 创建 INavigationService。使用从 XML 加载的自定义窗口进行导航

    远程计算机上的 C# 进程

    C# 基数 2 到十进制