You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决SAP导出CSV含中间双引号字段导致TextFieldParser解析失败

处理SAP导出CSV中字段内未转义双引号的TextFieldParser适配方案

问题核心

SAP导出的CSV存在不符合标准格式的情况:字段首尾用双引号包裹,但字段内部的双引号未按CSV规范转义(标准要求用两个双引号""表示字段内的一个双引号),比如示例行:

42000168,1004,10035,423,"1000 LB 3/8" DCD ORG", "HALB WIP",0

这种格式会导致启用HasFieldsEnclosedInQuotes = True的TextFieldParser误判字段结束位置,引发解析中断。

解决方案

方案1:预处理文件内容(简单高效)

先读取CSV文件内容,将字段内部的单个双引号替换为符合标准的双转义双引号,再用TextFieldParser解析处理后的内容。

使用正则表达式匹配双引号包裹字段内的单个双引号,替换为"",避免误替换字段外的双引号。

VB代码示例:

' 读取原始文件内容
Dim rawContent As String = File.ReadAllText(csvFile)
' 正则替换:匹配双引号对内部的单个双引号,替换为两个双引号
Dim processedContent As String = Regex.Replace(rawContent, "(?<=""[^""]*)""(?=[^""]*"")", """")

' 使用StringReader将处理后的内容传入TextFieldParser
Using reader As New StringReader(processedContent)
    Using parser As New TextFieldParser(reader)
        parser.TextFieldType = FieldType.Delimited
        parser.Delimiters = New String() {","}
        parser.HasFieldsEnclosedInQuotes = True

        While Not parser.EndOfData
            Dim fields As String() = parser.ReadFields()
            Dim row As DataRow = rawTable.NewRow()
            row("MTL") = fields(0)
            row("PL") = fields(1)
            row("MG") = fields(2)
            row("MRP") = fields(3)
            ' 解析后的字段内双引号会自动还原为单个
            row("MTLDESC") = fields(4)
            row("GPDESC") = fields(5)
            row("NET") = fields(6)

            rawTable.Rows.Add(row)
        End While
    End Using
End Using

方案2:自定义行解析逻辑(适合大文件)

如果CSV文件过大,全量读取内存占用过高,可以逐行读取并手动解析,跳过TextFieldParser的默认引号处理逻辑,自己判断字段边界。

VB代码示例:

Using reader As New StreamReader(csvFile)
    While Not reader.EndOfStream
        Dim line As String = reader.ReadLine()
        Dim fields As New List(Of String)()
        Dim currentField As New StringBuilder()
        Dim inQuotes As Boolean = False

        For Each c As Char In line
            Select Case c
                Case """"c
                    inQuotes = Not inQuotes
                    ' 记录双引号(后续可根据需求保留或移除)
                    currentField.Append(c)
                Case ","c
                    If Not inQuotes Then
                        ' 不在引号内的逗号是字段分隔符
                        fields.Add(currentField.ToString().Trim(""""c)) ' 移除首尾引号
                        currentField.Clear()
                    Else
                        ' 引号内的逗号作为字段内容的一部分
                        currentField.Append(c)
                    End If
                Case Else
                    currentField.Append(c)
            End Select
        Next

        ' 添加最后一个字段
        fields.Add(currentField.ToString().Trim(""""c))

        ' 填充DataRow
        Dim row As DataRow = rawTable.NewRow()
        row("MTL") = fields(0)
        row("PL") = fields(1)
        row("MG") = fields(2)
        row("MRP") = fields(3)
        ' 手动保留字段内的单个双引号
        row("MTLDESC") = fields(4)
        row("GPDESC") = fields(5)
        row("NET") = fields(6)

        rawTable.Rows.Add(row)
    End While
End Using

方案对比

  • 方案1:代码简洁,依赖TextFieldParser的成熟解析逻辑,适合中小体积文件;缺点是大文件会占用较多内存。
  • 方案2:逐行处理内存占用低,适合超大CSV;缺点是需要自己处理所有边界情况(如字段内换行、连续分隔符等)。

内容的提问来源于stack exchange,提问作者Andrew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 14:20:35