C#解析具有每行动态字段数的平面文件的最佳方法

时间:2012-11-07 23:22:11

标签: c# file parsing ssis

我有一个管道分隔的平面文件,看起来像这样的例子

可乐| COLB | 3 * |注1 |注2 |注3 | 2 ** | A1 | A2 | A3 | B1 | B2 | B3

前两列已设置并将始终存在。

*表示该计数后将有多少重复字段的计数,因此注1 2 3

**表示重复一个字段块的次数,并且块中总是有3个字段。

这是每行,因此每行可能具有不同数量的字段。

希望到目前为止有道理。

我正在尝试找到解析此文件的最佳方法,任何建议都会很棒。

最后的目标是将所有这些字段映射到几个不同的文件 - 数据转换。我实际上是在SSIS中做所有这些,但是认为默认组件不够好,所以需要编写自己的代码。

更新我本质上是尝试像源文件一样阅读它,并对其间的某些字段进行一些查找和字符串操作,并吐出几个不同的文件,就像在任何普通文件到文件转换SSIS包中一样。

使用上面的示例,我可能想要创建一个最终看起来像这样的新文件

“可乐”, “HardcodedString”, “Note1CRLFNote2CRLF”, “COLB”

然后是另一个文件

第1行:“ColA”,“A1”,“A2”,“A3”

第2行:“ColA”,“B1”,“B2”,“B3”

所以我想我正在考虑如何解析这个以及将数据存储在Stacks或Lists中?以后玩耍和吐出来。

3 个答案:

答案 0 :(得分:2)

一种可能性是使用堆栈。首先,您通过管道分割线。

var stack = new Stack<string>(line.Split('|'));

然后从堆栈中弹出前两个以使它们不碍事。

stack.Pop();
stack.Pop();

然后你解析下一个元素:3 *。为此,您可以弹出堆栈中的下3个项目。使用2 **,您可以从堆栈中弹出下一个2 x 3 = 6个项目,依此类推。一旦堆栈为空,您就可以停止。

while (stack.Count > 0)
{
    // Parse elements like 3*
}

希望这很清楚。我发现this article在String.Split()方面非常有用。

答案 1 :(得分:1)

类似下面的东西应该有用(这是未经测试的)

ColA|ColB|3*|Note1|Note2|Note3|2**|A1|A2|A3|B1|B2|B3

string[] columns = line.Split('|');
List<string> repeatingColumnNames = new List<string();
List<List<string>> repeatingFieldValues = new List<List<string>>();
if(columns.Length > 2)
{
    int repeatingFieldCountIndex = columns[2];
    int repeatingFieldStartIndex = repeatingFieldCountIndex + 1;
    for(int i = 0; i < repeatingFieldCountIndex; i++)
    {
        repeatingColumnNames.Add(columns[repeatingFieldStartIndex + i]);
    }

    int repeatingFieldSetCountIndex = columns[2 + repeatingFieldCount + 1];
    int repeatingFieldSetStartIndex =  repeatingFieldSetCountIndex + 1;

    for(int i = 0;  i < repeatingFieldSetCount; i++)
    {
        string[] fieldSet = new string[repeatingFieldCount]();

        for(int j = 0; j < repeatingFieldCountIndex; j++)
        {                             
            fieldSet[j] = columns[repeatingFieldSetStartIndex + j  + (i  * repeatingFieldSetCount))];
        }
        repeatingFieldValues.Add(new List<string>(fieldSet));
     }
}

答案 2 :(得分:-1)

System.IO.File.ReadAllLines("File.txt").Select(line => line.Split(new[] {'|'}))