如何逐行解析CSV文件,并解析出多个关键字及其数据
本文关键字:关键字 数据 文件 何逐行 逐行 CSV | 更新日期: 2023-09-27 18:03:40
我有一个CSV文件,其中包含如下数据(但更多):
Date dd/mm/yyyy
ExpirationDate dd/mm/yyyy
Lot 6760786776
Serial 34659FSFHS45
DataType Unknown Count
A(Loc1, Loc2) Unknown Variable1 Variable2 Variable3
B(Loc3, Loc4) Unknown Variable4 Variable5 Variable6
DataType Unknown Apple
A(Loc1, Loc2) Unknown Variable1 Variable2 Variable3
B(Loc3, Loc4) Unknown Variable4 Variable5 Variable6
等等……
目前,我有这样的东西:
public void DeserialCSVStream(string filePath)
{
using (StreamReader sr = new StreamReader(filePath))
{
string currentline;
while ((currentline = sr.ReadLine()) != null)
{
if (currentline.IndexOf("Date", StringComparison.CurrentCultureIgnoreCase) >=0)
{
Console.WriteLine(currentline);
}
else if (currentline.IndexOf("Lot", StringComparison.CurrentCultureIgnoreCase) >= 0)
{
Console.WriteLine(currentline);
}
else if (currentline.IndexOf("Serial", StringComparison.CurrentCultureIgnoreCase) >= 0)
{
Console.WriteLine(currentline);
}
else if (currentline.IndexOf("Count", StringComparison.CurrentCultureIgnoreCase) >= 0)
{
Console.WriteLine(currentline);
}
}
}
}
这是好的,但给了我一些问题:
-如果我寻找一个字符串"日期",它不仅给我日期,但到期日期,但我只想解析出日期。如果我使用StartsWith,它会给我null
—同样,上面的代码只允许我抓取字段旁边的列数据。例如,计数只返回数据类型和未知,但我想抓住计数下的整个"表",而不仅仅是计数所在的那一行。我怎么做呢?
这看起来像一个自定义格式的文本文件,而不是CSV(逗号分隔值)文件。
你可以稍微修改一下你的代码,通过使用StartsWith而不是IndexOf来解决特定的问题
if (currentline.StartsWith("Date:", StringComparison.CurrentCultureIgnoreCase))
如果有可能有前导空格,可以将currentLine
改为currentLine.TrimStart()
如果您知道文件头总是相同的,您应该只显式地读取前四行。干净,简单,整体性能也会更好。
public void DeserialStream(string filePath)
{
using (var sr = new StreamReader(filePath))
{
// header
var dateLine = sr.ReadLine();
var expirationDateLine = sr.ReadLine();
var lotLine = sr.ReadLine();
var serialLine = sr.ReadLine();
// skip next two lines
sr.ReadLine();
sr.ReadLine()
// csv data
string currentline;
while ((currentline = sr.ReadLine()) != null)
{
Console.WriteLine(currentline);
}
}
}
我会使用正则表达式来获得您想要的行。有了它们,你可以很容易地指定你想要的格式。此外,我猜您稍后会想要从这些行中提取一些值。对于正则表达式,您可以通过使用分组构造来获取值。
对于日期示例,一个可能的正则表达式类似于
string dateRegex = @"Date: 'd'd/'d'd/'d'd'd'd"
要使用分组构造获得日期值,
string dateRegex = @"Date: (?<day>'d'd)/(?<month>'d'd)/(?<year>'d'd'd'd)"
然后通过键"date"、"month"answers"year"从解析表达式的组中获得值。
您可以使用Dictionary<string, string>
,关键是术语和值是…值。然后,您可以使用String.StartsWith
和StringcComparison.CurrentCultureIgnoreCase
来检查该行是否以该术语开头。您可以使用字符串方法(如Substring
或IndexOf
)获取该值。我假设您正在寻找空格后面的值:
var lines = File.ReadLines(filePath);
var tokenValues = new Dictionary<string,string>{ { "Date", null }, { "Lot", null }, { "Serial", null } };
foreach (string line in lines)
{
string l = line.TrimStart();
string startsWithToken = tokenValues.Keys
.FirstOrDefault(t => l.TrimStart().StartsWith(t, StringComparison.CurrentCultureIgnoreCase));
if(startsWithToken != null)
tokenValues[startsWithToken] = l.Substring(l.IndexOf(' ') + 1).Trim();
}