CSV Helper,读取字段数据中带双引号的文件

Ali*_*Ali 7 c# double-quotes csvhelper

我需要一些帮助,用 C# 中的 CSV Helper 进行 CSV 解析

我的示例文件是

"SKU","Title","URL","BP","SP","NumberOf","Wid1","Wid2","Wid3"
"Big Corp","CRM updates","test","0","0","0","0","0","0"
"Big Corp 1","CRM "test" updates","test","0","0","0","0","0","0"
Run Code Online (Sandbox Code Playgroud)

我的配置是

using (TextReader reader = File.OpenText(location))
            {
                using (var csv = new CsvReader(reader, System.Globalization.CultureInfo.CurrentCulture))
                {
                    csv.Configuration.RegisterClassMap<ProductMap>();
                    List<Product> records = csv.GetRecords<Product>().ToList();
                    return records;
                }
            }
Run Code Online (Sandbox Code Playgroud)

我在最后一行中收到错误,其中 1 个字段中有双引号。如果我想转义/删除双引号,我需要做什么设置?

我还尝试替换映射文件中的双引号,但双引号显示在错误的位置。双引号位于“测试”一词上,但在数据中它们显示在“更新”一词上。

在此输入图像描述

进而

在此输入图像描述

我可以在映射文件中用空字符串替换双引号,但是还有其他解决方案吗?

Dav*_*cht 3

您可以使用 来完成此操作CsvMode.NoEscape,这将在每个字段的末尾留下引号。(如果任何字段包含换行符,它也会中断)。然后,您可以使用自定义转换器来修剪每个字段的外引号。我只是希望有一个类似的配置PrepareHeaderForMatch可用于在映射字段之前处理字段。

void Main()
{
    var config = new CsvConfiguration(CultureInfo.InvariantCulture)
    {
        PrepareHeaderForMatch = args => args.Header.Trim('\"'),
        Mode=CsvMode.NoEscape
    };
    
    var data = new StringBuilder();
    data.AppendLine("\"SKU\",\"Title\",\"URL\",\"BP\",\"SP\",\"NumberOf\",\"Wid1\",\"Wid2\",\"Wid3\"");
    data.AppendLine("\"Big Corp\",\"CRM updates\",\"test\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"");
    data.AppendLine("\"Big Corp 1\",\"CRM \"test\" updates\",\"test\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"");

    using (var reader = new StringReader(data.ToString()))
    using (var csv = new CsvReader(reader, config))
    {
        csv.Context.TypeConverterCache.AddConverter<int>(new IntTrim());
        csv.Context.TypeConverterCache.AddConverter<string>(new StringTrim());
        csv.GetRecords<Product>().ToList().Dump();
    }
}

public class StringTrim : StringConverter
{
    public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
    {
        return base.ConvertFromString(text?.Trim('"'), row, memberMapData);
    }
}

public class IntTrim : Int32Converter
{
    public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
    {
        return base.ConvertFromString(text?.Trim('"'), row, memberMapData);
    }
}

public class Product
{
    public string SKU { get; set; }
    public string Title { get; set; }
    public string URL { get; set; }
    public int BP { get; set; }
    public int SP { get; set; }
    public int NumberOf { get; set; }
    public int Wid1 { get; set; }
    public int Wid2 { get; set; }
    public int Wid3 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)