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

C#解析含引号数组字段的CSV:替代line.Split(',')的方案

解决C#中带引号嵌套逗号的CSV解析问题

这个场景太常见了!直接用string.Split(',')肯定会踩坑,因为引号包裹的内容里的逗号是字段内部的,不是分隔符。在C#里有几种高效的解决方案,我给你逐一说明:

方法1:使用.NET内置的TextFieldParser

虽然它在Microsoft.VisualBasic.FileIO命名空间下,但别担心,.NET Core/.NET 5+都能直接用,不需要额外安装库,适合轻量场景。

首先定义你的目标类:

public class MyCsvData
{
    public string[] Letters { get; set; }
    public string Foo { get; set; }
    public string Goo { get; set; }
}

然后编写解析代码:

using Microsoft.VisualBasic.FileIO;
using System.Collections.Generic;
using System.IO;

public List<MyCsvData> ParseCsv(string filePath)
{
    var result = new List<MyCsvData>();

    using (var parser = new TextFieldParser(filePath))
    {
        parser.TextFieldType = FieldType.Delimited;
        parser.SetDelimiters(",");
        parser.HasFieldsEnclosedInQuotes = true; // 关键:告诉解析器处理引号包裹的字段

        while (!parser.EndOfData)
        {
            string[] fields = parser.ReadFields();
            // 第一个字段是引号包裹的"a1,b1,c1,d1",直接分割成数组
            string[] letters = fields[0].Split(',');
            // 后续字段直接取,注意去除可能的空格
            var data = new MyCsvData
            {
                Letters = letters,
                Foo = fields[1].Trim(),
                Goo = fields[2].Trim()
            };
            result.Add(data);
        }
    }

    return result;
}

这个方法会自动忽略引号内的逗号,正确分割出三个顶级字段:"a1,b1,c1,d1"、foo1、goo1,然后你再把第一个字段分割成数组即可。

方法2:使用第三方库CsvHelper(推荐)

如果你的CSV格式更复杂(比如有转义引号、多行字段等),CsvHelper是行业标准,功能强大且灵活。

首先通过NuGet安装CsvHelper包,然后编写代码:

using CsvHelper;
using CsvHelper.Configuration;
using System.Collections.Generic;
using System.Globalization;
using System.IO;

// 定义目标类
public class MyCsvData
{
    public string[] Letters { get; set; }
    public string Foo { get; set; }
    public string Goo { get; set; }
}

// 定义字段映射规则
public class MyCsvDataMap : ClassMap<MyCsvData>
{
    public MyCsvDataMap()
    {
        Map(m => m.Letters).Convert(args => args.Row.GetField<string>(0).Split(','));
        Map(m => m.Foo).Index(1).Trim();
        Map(m => m.Goo).Index(2).Trim();
    }
}

public List<MyCsvData> ParseCsvWithCsvHelper(string filePath)
{
    var config = new CsvConfiguration(CultureInfo.InvariantCulture)
    {
        Delimiter = ",",
        Quote = '"',
        TrimOptions = TrimOptions.Trim // 自动去除字段前后空格
    };

    using (var reader = new StreamReader(filePath))
    using (var csv = new CsvReader(reader, config))
    {
        csv.Context.RegisterClassMap<MyCsvDataMap>();
        return csv.GetRecords<MyCsvData>().ToList();
    }
}

CsvHelper会自动处理所有CSV的边缘情况,而且代码更简洁易维护,非常适合生产环境使用。

方法3:手动解析(不推荐,除非特殊场景)

如果不想用任何库,你可以手动遍历字符,跟踪是否处于引号内,遇到逗号时只有在引号外才分割。但这种方式需要处理很多边界情况(比如转义的""、空字段等),示例代码大概是这样:

public List<MyCsvData> ParseCsvManually(string filePath)
{
    var result = new List<MyCsvData>();
    foreach (var line in File.ReadLines(filePath))
    {
        var fields = new List<string>();
        bool inQuotes = false;
        var currentField = new char[line.Length];
        int idx = 0;

        foreach (char c in line)
        {
            if (c == '"')
            {
                inQuotes = !inQuotes;
            }
            else if (c == ',' && !inQuotes)
            {
                fields.Add(new string(currentField, 0, idx).Trim());
                idx = 0;
            }
            else
            {
                currentField[idx++] = c;
            }
        }
        // 添加最后一个字段
        fields.Add(new string(currentField, 0, idx).Trim());

        if (fields.Count >=3)
        {
            result.Add(new MyCsvData
            {
                Letters = fields[0].Split(','),
                Foo = fields[1],
                Goo = fields[2]
            });
        }
    }
    return result;
}

这种方式容易遗漏场景,比如如果字段里有""(表示一个双引号),上面的代码就处理不了,所以除非万不得已,优先用前两种方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:56:35