解析用逗号分隔的文本文件

时间:2013-04-25 09:40:44

标签: c# fileparsing

我正在开发一个应用程序来读取文本文件并绘制图形。文本文件将类似于

#Pattern Name Item1, Item2, Item3, gx1, gy1, gz1 
115, 80, 64, 30.752, 27.587, 15.806 
195, 151, 130, 108.983, 102.517, 66.353 
94, 123, 156, 43.217, 50.874, 93.700 
88, 108, 65, 26.158, 37.980, 17.288 
130, 129, 177, 68.096, 66.289, 127.182 
100, 190, 171, 71.604, 119.764, 122.349 
.........................................
........................................
#Pattern Name2 Item1, Item2, Item3, gx1, gy1, gz1 
115, 80, 64, 30.752, 27.587, 15.806 
195, 151, 130, 108.983, 102.517, 66.353 
94, 123, 156, 43.217, 50.874, 93.700 
88, 108, 65, 26.158, 37.980, 17.288 
130, 129, 177, 68.096, 66.289, 127.182 
100, 190, 171, 71.604, 119.764, 122.349

我需要值gx1,gy1。我计划通过计算空格和逗号来读取它们(每个3个)。但这听起来合适吗?是否有任何优化或更好的逻辑?

4 个答案:

答案 0 :(得分:2)

如何使用Linq?

var allparts = File.ReadLines(filename)
                .Where(line => !line.StartsWith("#"))
                .Select(line => line.Split(','))
                .Select(parts => new {gx1=parts[3], gy1=parts[4]} ) 
                .ToList();

答案 1 :(得分:1)

您拥有的是一个简单的CSV文件。我会建议:

1)使用CSV解析库(例如http://www.filehelpers.com/
2)逐行解析这个问题:

String[] lines = File.ReadAllLines(...);
foreach(String line in lines)
{
   String parts[] = line.Split(",", StringSplitOptions.IgnoreEmpty);
   double gx1 = Double.Parse(parts[5]);
   double gx2 = Double.Parse(parts[6]);
}

但是,您需要为特殊行添加一些验证/换行

答案 2 :(得分:1)

您应该使用现有的csv-parser,如this

但是,假设模式的名称是唯一的,并且您希望稍后访问它:

var gxDict = new Dictionary<string, List<Tuple<double, double>>>();
List<Tuple<double, double>> currentGxList = null;
foreach (string line in File.ReadLines(filePath))
{
    if (line.StartsWith("#Pattern"))
    {
        string[] headers = line.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
        string patternField = headers.First();
        string patterName = string.Join(" ", patternField.Split().Skip(1).Take(2));
        List<Tuple<double, double>> gxList = null;
        if (gxDict.TryGetValue(patterName, out gxList))
            currentGxList = gxList;
        else
        {
            currentGxList = new List<Tuple<double, double>>();
            gxDict.Add(patterName, currentGxList);
        }
    }
    else
    {
        if (currentGxList != null)
        {
            string[] values = line.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            double gx1;
            double gy1;
            string gx1Str = values.ElementAtOrDefault(3);
            string gy1Str = values.ElementAtOrDefault(4);
            if (double.TryParse(gx1Str, out gx1) && double.TryParse(gx1Str, out gy1))
            {
                currentGxList.Add(Tuple.Create(gx1, gy1));
            }
        }
    }
}

//现在您可以通过以下方式访问它:

List<Tuple<double, double>> nameItem1Vals = gxDict["Name Item1"];
foreach (var xy in nameItem1Vals)
    Console.WriteLine("gx1: {0} gy1: {1}", xy.Item1, xy.Item2);

//或循环:

foreach (var kv in gxDict)
{
    string pattern = kv.Key;
    Console.WriteLine("pattern: {0}", pattern);
    foreach (var xy in nameItem1Vals)
        Console.WriteLine("gx1: {0} gy1: {1}", xy.Item1, xy.Item2);
}

请注意,在涉及IO的{​​{1}}时,我要避免使用Linq,您需要在文件级别进行事件处理,并且当我尝试解析也可能导致异常的输入时。

答案 3 :(得分:0)

读取每一行然后行.Split(“,”)怎么样? 你可以拥有的Sou:

var items = line.Split(", ");
var gx1 = items[3];
var gy1 = items[4];
var gz1 = items[5];