【问题标题】:Parsing CSV file with un-escaped quotation marks and commas in .NET在.NET中解析带有未转义引号和逗号的CSV文件
【发布时间】:2009-04-22 09:46:00
【问题描述】:

我想知道是否有人可以帮助我。

我必须从 csv 文件中解析数据并将其放入 db 表中。数据示例如下:

“第一个字段”、“第二个字段”、“第三个字段”、“第四个字段”

如您所见,字段中嵌入了引号和逗号。我使用的是 ADO.NET,但嵌入的引号存在问题。嵌入引号后的任何字段都将为空

例如从上面的示例中,以下内容将被插入到 DB 表中。

first field  |  second, field   |  third     | NULL

这是我正在使用的代码。

    Dim dataTable As New DataTable
    Dim dataAdapter As New OleDbDataAdapter

    Dim cmd As New OleDbCommand
    Dim path As String = "c:\"


        Dim conn As OleDbConnection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" _
           & System.IO.Path.GetDirectoryName(filename) & ";Extended Properties=""Text;HDR=Yes;FMT=Delimited""")

        cmd.CommandText = "Select * FROM " & System.IO.Path.GetFileName(filename)
        dataAdapter.SelectCommand = cmd
        cmd.Connection = conn
        conn.Open()
        dataAdapter.Fill(dataTable)

然后我将数据插入到 db 表中。

对此的任何建议或指导将不胜感激。

【问题讨论】:

    标签: .net string parsing csv


    【解决方案1】:

    目前还没有真正理解答案。

    据我所知,如果不添加额外限制,则无法解析您的示例输入字符串。

    出现问题的是您的第三个字段。解析器如何判断“在第三个和字段之间的”之后我们还没有完成第三个元素?通过检测到后面的字符不是逗号?如果第三个字段也包含逗号怎么办,是否允许?

    "first field", "second , field", "third ", Field " ", "fourth field"
    

    此时,您将进入多次试验和错误解析(尽管我不是专家)。也就是说,解析器必须到达字段的 F,并意识到这是不可解析的,备份并在第三个字段中包含 ", 并继续执行以下 "...等

    [即使 Excel 也无法处理该字符串。]

    【讨论】:

    • 假设一个规则是引号成对出现。在那之后它的复杂性降低了。观察到给定工具无法应对并不意味着问题无法解决。
    • 如果引号成对出现,是否排除引号内的成对引号? Excel 只是一个例子。
    【解决方案2】:

    这可能有点挑战 - 但是编写代码来手动解析一行 csv 数据相当简单。

    基本上你有两种可能的情况:

    1. 保证每个字段都用双引号分隔
    2. 任何包含逗号的字符串都将用双引号括起来 - 如果您在带引号的字符串中包含逗号,那么事情可能会变得有趣,因此您可能必须限制您想要变得多么聪明(所提供的data 可以包含)。

    对于第一种情况,基本上您所要做的就是在“,”组合上拆分字符串(这可能必须手动完成)-记住从第一列/项目中删除前导“和尾随”最后一列/项目 - 你几乎在那里。

    对于第二种情况,您必须做更多的工作 - 要么 a) 在每个逗号上拆分行,然后处理结果,将相邻的项目缝合在一起,其中项目以双引号开头但不以 (你连接字段 - 不要忘记包含逗号 - '直到你找到以“结尾但不以一个开头的相应项目)或b)在每次迭代时循环遍历字符串你从列表中拉出第一个项目(如果它以“那么你正在寻找”开头,则结束它,否则你只是在寻找一个逗号,并且在这两种情况下都允许没有找到分隔符的边界情况,因为你正在查看最后一栏。

    希望这会有所帮助。有点。

    【讨论】:

      【解决方案3】:

      您可以尝试将分隔字段的引号与不检查以下正则表达式是否可以匹配前面或后面字符 @"\p{Z},\p{Z} 的引号区分开来" 使用相同的概念,您可以通过附近的引号来区分文本中的逗号,而不是分隔逗号。 运行这些启发式方法并转义不符合上述规则的逗号和引号应该会产生一个非常干净的结果 当然,在某些情况下这可能无法正常工作,但据我所知,如果 CSV 未转义,则没有更好的方法来处理这个问题。

      【讨论】:

        【解决方案4】:

        如果您的代码不需要成为应用程序的一部分,但您只想生成 SQL 语句以从 CSV 数据更新数据库,您可能会对我自己的 CSVFix 项目感兴趣,它是 FOSS 并允许您无需编程即可以多种方式操作 CSV 数据。

        【讨论】:

          【解决方案5】:

          酷。感谢您的所有帮助。我正在处理的文件非常大,因此手动解析效率不高。

          我已经通过获取带有转义引号的正确 csv 文件并在没有发生这种情况时添加验证和错误处理来解决该问题。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-02-18
            • 1970-01-01
            • 1970-01-01
            • 2013-03-09
            相关资源
            最近更新 更多