如何逐行解析CSV并解析出多个关键字及其数据?

时间:2014-05-16 20:48:52

标签: c# csv

我有一个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。

- 而且,上面只让我抓住字段旁边的列数据。例如。 Count只返回DataType和Unknown但是我想在count下获取整个“table”而不仅仅是Count所在的那一行。我怎么做?

4 个答案:

答案 0 :(得分:0)

它看起来像是带有自定义格式的文本文件,而不是CSV(逗号分隔值)文件。

您可以使用StartsWith而不是IndexOf

稍微修改代码以修复您要解决的特定问题
if (currentline.StartsWith("Date:", StringComparison.CurrentCultureIgnoreCase))

如果可能有任何领先空格,您可以将currentLine更改为currentLine.TrimStart()

答案 1 :(得分:0)

如果您知道文件头始终相同,则应该只显式读取前四行。干净,简单,整体表现也会更好。

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);

        }
    }
}

答案 2 :(得分:0)

您可以使用Dictionary<string, string>,关键是术语,值是......值。然后,您可以String.StartsWithStringcComparison.CurrentCultureIgnoreCase一起使用来检查该行是否以该字词开头。您可以使用SubstringIndexOf等字符串方法获取值。我假设您正在寻找空间之后的值:

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();
}

答案 3 :(得分:0)

我会使用正则表达式来获取所需的行。有了它们,您可以轻松指定您期望的格式。此外,我想你以后想要从这些行中提取一些值。使用正则表达式,您可以使用分组构造来获取值。

对于日期示例,一个可能的正则表达式将类似于

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)"

然后,通过键&#34; date&#34;,&#34; month&#34;从解析的表达式组中获取值。和&#34;年&#34;。