C#读取带引号且字段含逗号的CSV转数组时分割错误如何解决
修复方案
方案1:使用.NET内置标准CSV解析器(推荐,无第三方依赖)
手动实现CSV分割逻辑会遗漏大量标准CSV的边缘场景:除了引号包裹字段内的逗号,还会遇到字段内转义双引号(标准CSV中字段内的双引号会写为连续两个"")、字段内换行等情况,简单的Split无法覆盖所有规则。
.NET 官方内置了符合RFC 4180标准的CSV解析器TextFieldParser,C# 项目可直接使用,无需安装任何第三方包,跨平台版本的.NET Core/.NET 5+ 也完全支持:
- 首先为项目添加框架程序集引用
Microsoft.VisualBasic - 读取代码实现如下:
using Microsoft.VisualBasic.FileIO; using System.Collections.Generic; using System.IO; var filePath = @"C:\Users\sti\source\repos\AutoAppr\AutoAppr\bin\Debug\Spreadsheet.csv"; var data = new List<string[]>(); using (var parser = new TextFieldParser(filePath)) { parser.TextFieldType = FieldType.Delimited; parser.SetDelimiters(","); // 自动处理双引号包裹的字段 parser.HasFieldsEnclosedInQuotes = true; while (!parser.EndOfData) { string[] row = parser.ReadFields(); data.Add(row); } } // 得到和原有代码结构一致的二维数组结果 var dataArray = data.ToArray();
该实现会自动识别双引号包裹的字段边界,不会错误拆分字段内部的逗号,同时自动剥离字段外层的包裹引号,所有标准CSV格式的规则都已内置处理。
方案2:轻量手动分割实现(仅适用于格式固定的简单CSV场景)
如果你的CSV格式非常固定,不存在转义引号、字段内换行的情况,也不想引用额外程序集,可以实现一个简单的状态机分割逻辑,替换原有的x.Split(','):
private static string[] SplitSimpleCsvLine(string line) { var fields = new List<string>(); var current = new StringBuilder(); bool inQuotedField = false; foreach (char c in line) { if (c == '"') { inQuotedField = !inQuotedField; continue; } if (c == ',' && !inQuotedField) { fields.Add(current.ToString()); current.Clear(); continue; } current.Append(c); } fields.Add(current.ToString()); return fields.ToArray(); }
将原代码的读取逻辑替换为var data = File.ReadLines(filePath).Select(SplitSimpleCsvLine).ToArray();即可处理引号包裹字段内带逗号的场景。注意该实现仅适配最基础的引号包裹格式,遇到转义引号、跨行字段会解析错误,复杂场景优先使用方案1。
之前尝试的写法问题说明
string.Split并非完全不支持字符串作为分隔符,之前想的按","分割的逻辑可以通过如下重载实现:
x.Split(new[] {"\",\""}, StringSplitOptions.None)
但这种写法会残留行首第一个字段的前引号、行尾最后一个字段的后引号,且如果字段内部本身包含","字符串就会出现错误拆分,鲁棒性极差,不建议使用。
内容的提问来源于stack exchange,提问作者user2668641
相关产品推荐
相关产品推荐

