0

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

ColA|ColB|3*|注1|注2|注3|2**|A1|A2|A3|B1|B2|B3

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

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

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

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

希望到目前为止这是有道理的。

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

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

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

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

"ColA","HardcodedString","Note1CRLFNote2CRLF","ColB"

然后另一个文件

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

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

所以我想我想知道如何解析这个以及将数据存储在堆栈或列表中还是?玩,以后吐出来。

4

3 回答 3

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*
}

希望这足够清楚。我发现这篇文章对于 String.Split() 非常有用。

于 2012-11-07T23:34:41.647 回答
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));
     }
}
于 2012-11-08T00:58:44.443 回答
-1
System.IO.File.ReadAllLines("File.txt").Select(line => line.Split(new[] {'|'}))
于 2012-11-07T23:31:29.170 回答