如何解决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
相关产品推荐
相关产品推荐

