C# 解析CSV,其中头包含带有CsvHelper的空格
我有一个带有字段标题的CSV文件,其中一些文件包含两个或三个用空格分隔的单词: 您可以在上图中看到包含空格的字段标题:C# 解析CSV,其中头包含带有CsvHelper的空格,c#,csv,csvhelper,C#,Csv,Csvhelper,我有一个带有字段标题的CSV文件,其中一些文件包含两个或三个用空格分隔的单词: 您可以在上图中看到包含空格的字段标题: “时间”、“进程名称”和“映像路径” 当我试图通过调用reader.GetRecords()读取CSV时(其中,DataRecord是我定义的一个类),我得到错误: CSV文件中不存在“TimeOfDay”字段。“* 这是因为我的DataRecord类不能包含带有空格的成员 如何使用CsvHelper解析CSV文件?基于CsvHelper,有几种方法可以实现我们想要的结果 1
“时间”、“进程名称”和“映像路径” 当我试图通过调用
reader.GetRecords()读取CSV时
(其中,DataRecord
是我定义的一个类),我得到错误:
CSV文件中不存在“TimeOfDay”字段。“*
这是因为我的DataRecord
类不能包含带有空格的成员
如何使用CsvHelper解析CSV文件?基于CsvHelper,有几种方法可以实现我们想要的结果
1.忽略标题中的空白(我相信这会很容易解决您的问题)
在CsvHelper 3或更高版本中,使用prepareHeadPerformatch
(记录在)删除标题中的空白:
csv.Configuration.PrepareHeaderForMatch =
header => Regex.Replace(header, @"\s", string.Empty)
在CsvHelper 2中,设置IgnoreHeaderWhiteSpace
标志,告知读者在按名称将列与属性匹配时忽略标题中的空白
reader.Configuration.IgnoreHeaderWhiteSpace = true;
2.手动读取
我们可以手动读取每个字段,如:
var reader = new CsvReader(sr);
do
{
reader.Read();
var record=new DataRecord();
record.TimeOfDay=reader.GetField<string>("Time of Day");
record.ProcessName=reader.GetField<string>("Process Name");
record.PID=reader.GetField<string>("PID");
record.Operation=reader.GetField<string>("Operation");
record.Path=reader.GetField<string>("Path");
record.Result=reader.GetField<string>("Result");
record.Detail=reader.GetField<string>("Detail");
record.ImagePath=reader.GetField<string>("Image Path");
} while (!reader.IsRecordEmpty());
然后,我们应使用以下方式进行注册:
reader.Configuration.RegisterClassMap<DataRecordMap>();
reader.Configuration.RegisterClassMap();
该库现在支持。您可能希望使用该属性
using CsvHelper.Configuration.Attributes;
public class DataRecord
{
[Name("Time of Day")]
public string TimeOfDay { get; set; }
[Name("Process Name")]
public string ProcessName { get; set; }
public string PID { get; set; }
public string Operation { get; set; }
public string Path { get; set; }
public string Result { get; set; }
public string Detail { get; set; }
[Name("Image Path")]
public string ImagePath { get; set; }
public static IEnumerable<DataRecord> ParseDataRecords(Stream file)
{
using (var sr = new StreamReader(file))
using (var csv = new CsvReader(sr))
{
foreach (var record in csv.GetRecords<DataRecord>())
{
yield return record;
}
}
}
}
使用CsvHelper.Configuration.Attributes;
公共类数据记录
{
[名称(“一天中的时间”)]
公共字符串TimeOfDay{get;set;}
[名称(“流程名称”)]
公共字符串ProcessName{get;set;}
公共字符串PID{get;set;}
公共字符串操作{get;set;}
公共字符串路径{get;set;}
公共字符串结果{get;set;}
公共字符串详细信息{get;set;}
[名称(“图像路径”)]
公共字符串ImagePath{get;set;}
公共静态IEnumerable ParseDataRecords(流文件)
{
使用(var sr=新的StreamReader(文件))
使用(var csv=新的CsvReader(sr))
{
foreach(csv.GetRecords()中的var记录)
{
收益回报记录;
}
}
}
}
虽然看起来不错,但方法1似乎不再起作用。预期的函数现在需要两个参数。添加一个参数后,返回值似乎没有被使用,该方法没有任何效果。@kjyv我使用csv.Configuration.prepareHeadPerformatch=(header,index)=>Regex.Replace(header,index)=>Regex.Replace(header,@“\s使其工作起来“,字符串。空)代码>只是好奇是否有人编写了一个“列名不匹配调试器”,这样它就不会抛出一个错误,说它找不到匹配项,而是尝试查找与映射中的任何单词匹配的任何列。例如,我有一个名为“RatingAgency”的专栏,但得到一个错误消息:什么都不存在。虽然我希望它在开发过程中很难失败,但我也希望它在开发过程中说:“哦,嘿,约翰,以下专栏部分匹配:“评级机构,评级”
using CsvHelper.Configuration.Attributes;
public class DataRecord
{
[Name("Time of Day")]
public string TimeOfDay { get; set; }
[Name("Process Name")]
public string ProcessName { get; set; }
public string PID { get; set; }
public string Operation { get; set; }
public string Path { get; set; }
public string Result { get; set; }
public string Detail { get; set; }
[Name("Image Path")]
public string ImagePath { get; set; }
public static IEnumerable<DataRecord> ParseDataRecords(Stream file)
{
using (var sr = new StreamReader(file))
using (var csv = new CsvReader(sr))
{
foreach (var record in csv.GetRecords<DataRecord>())
{
yield return record;
}
}
}
}