验证CSV文件是否将分隔符作为数据的一部分

时间:2014-09-17 10:51:37

标签: c# linq csv

我有一个CSV文件,需要检查分隔符不是数据的一部分。

假设它有两列,分隔符是逗号。

标题:

Column1, Column2

和这样的数据:

data1, data2
data3, data3,3

第二行,第二列数据无效,因为它中有逗号。 我可以读取每一行并根据分隔符将其拆分并检查数组长度。 在这种情况下,如果它大于2,则数据无效。

有没有其他方法可以使用LINQ或任何可以帮助我的外部库。

问候。

2 个答案:

答案 0 :(得分:1)

这样的东西
 var content = new List<string>();
        using (StreamReader reader = new StreamReader(path)) 
        {
            string line = reader.ReadLine();

            while (line != null)
            {
                content.Add(line);
                line = reader.ReadLine();          //read in all lines

            }
        }
//var content = File.ReadAllLines(path, Encoding.ASCII); //bad practice, see comments
var vaildContent = (from val in content                       //specify source ("content"), create temporary var ("val") for processing
                                where val.Split(new []{","},  StringSplitOptions.RemoveEmptyEntries).Length == 2  // condition(s)
                                select val).ToList(); //If condition is true, slect the object
即使我认为不需要linq,

也会实现你想要的。因为你可以扩展它(用我们基于文件头构建的自定义值替换我的硬编码“2”)。

答案 1 :(得分:0)

您可以先计算标题,计算它应该是多少列。然后对于每个数据,用逗号分割并在标题中删除多个列。

var lines = File.ReadLines(path);

// need to check how many lines returned before reaching here
var header = lines.FirstOrDefault();
var count = (header ?? string.Empty).Count(x => x == ',') + 1;
var data = lines
    .Skip(1)
    .Select(x => x
        .Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
        .Take(count)
        .ToArray());
使用StreamReader代替File.ReadLines(path)

更新并将其包装在方法中。

static IEnumerable<string[]> ReadCsv(string path)
{
    using (var stream = new StreamReader(path))
    {
        var line = stream.ReadLine();
        if (line != null)
        {
            var count = line.Count(x => x == ',') + 1;
            while ((line = stream.ReadLine()) != null)
            {
                var data = line
                    .Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
                    .Take(count)
                    .ToArray();
                yield return data;
            }
        }
    }
}

用法

IEnumerable<string[]> lines = ReadCsv(path);

更新2 正如@Juharr所建议的,ReadAllLines已替换为ReadLines,以便在返回整行之前可以枚举这些行。