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

C#解析含逗号金额列CSV转JSON 避免金额字段截断错误

问题根源

原有代码直接通过string.Split(',')拆分每行内容的逻辑不符合RFC 4180 CSV规范,无法识别双引号包裹的字段边界,当字段内部包含逗号时(如示例中的"$2,651.98"),会错误拆分字段,最终导致值截断、字段错位。

解决方案

不推荐手动编写CSV分割逻辑:CSV格式除内嵌逗号场景外,还存在双引号转义、字段内嵌换行、前后空白符处理等大量边界情况,手动实现极易遗漏场景触发解析异常,优先选择成熟解析方案。

方案1:使用CsvHelper组件实现(生产环境推荐)

CsvHelper是C#生态中广泛使用的CSV处理组件,默认遵循RFC 4180标准,可自动识别双引号包裹的内嵌逗号字段,搭配Newtonsoft.Json可快速完成转换,稳定性高。

  1. 将CsvHelper组件引入项目
  2. 参考实现代码如下:
using CsvHelper;
using CsvHelper.Configuration;
using Newtonsoft.Json;
using System.Globalization;
using System.IO;

// 配置CSV解析规则
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
    HasHeaderRecord = true, // 指定首行为表头
    TrimOptions = TrimOptions.Trim, // 自动去除字段前后多余空白
    Mode = CsvMode.RFC4180 // 按标准CSV格式解析,自动处理引号包裹字段
};

// 读取CSV字符串内容
using (var reader = new StringReader(csvResponseData))
using (var csv = new CsvReader(reader, config))
{
    // 自动映射表头与字段值,读取为结构化对象
    var records = csv.GetRecords<dynamic>().ToList();
    // 序列化为JSON返回
    return JsonConvert.SerializeObject(records);
}

该方案可完整识别示例中"$2,651.98"、"$3,252.97"这类带逗号的金额字段,不会出现拆分错误。

方案2:无第三方依赖的轻量实现

如果不希望引入外部组件,可自行实现符合基础CSV规范的字段分割方法,替换原有Split(',')逻辑即可。
首先实现单行CSV字段解析方法:

private static List<string> ParseCsvLine(string line)
{
    var fields = new List<string>();
    var currentField = new StringBuilder();
    bool inQuotedField = false;

    for (int i = 0; i < line.Length; i++)
    {
        char c = line[i];
        if (c == '"')
        {
            // 处理双引号转义:两个连续双引号代表字段内的一个双引号字符
            if (inQuotedField && i < line.Length - 1 && line[i + 1] == '"')
            {
                currentField.Append('"');
                i++;
            }
            else
            {
                // 切换引号包裹状态
                inQuotedField = !inQuotedField;
            }
        }
        else if (c == ',' && !inQuotedField)
        {
            // 仅当不在引号包裹范围内时,逗号才作为字段分隔符
            fields.Add(currentField.ToString().Trim('\\').Trim());
            currentField.Clear();
        }
        else
        {
            currentField.Append(c);
        }
    }
    // 追加最后一个字段
    fields.Add(currentField.ToString().Trim('\\').Trim());
    return fields;
}

再修改原有解析逻辑,将所有直接调用Split(',')的位置替换为上述方法:

var lines = csvResponseData.Split('\n');
// 解析表头
var properties = ParseCsvLine(lines[0]);
var listObjResult = new List<Dictionary<string, string>>();

for (int i = 1; i < lines.Length; i++)
{
    if (lines[i].Length > 5)
    {
        var objResult = new Dictionary<string, string>();
        // 解析当前行字段
        var lineFields = ParseCsvLine(lines[i]);
        for (int j = 0; j < properties.Count; j++)
        {
            if (j < lineFields.Count)
            {
                objResult.Add(properties[j], lineFields[j]);
            }
        }
        listObjResult.Add(objResult);
    }
    else
    {
        break;
    }
}
return JsonConvert.SerializeObject(listObjResult);

注意:轻量实现仅覆盖常规CSV场景,如果文件存在字段内嵌换行、特殊转义字符等复杂格式,优先选择成熟组件方案。

解析效果验证

针对给出的CSV示例,修正后可正确识别所有字段,无截断问题:

  • textbox69字段完整值为 $2,651.98
  • textbox71字段完整值为 $3,252.97
  • 其余无特殊字符的字段解析结果与原有逻辑一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 23:09:24