我有一个管道分隔的平面文件,看起来像这样的例子
可乐| 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中?以后玩耍和吐出来。
答案 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[] {'|'}))