我正在尝试解析格式化为列的文本报告。每列似乎都是右对齐的,具有固定的长度。对于每一行,有时并非所有列都被使用。在这种情况下,空格似乎用于对齐行中的每一列。输入示例:
031 91 1221,154
043 66 312,222 1 3,047 3,047 1.5% .9%
040 118 529,626 1 1,842 1,842 .8% .3%
037 45 427,710
019 80 512,153 1 14,685 14,685 1.2% 2.8%
009 68 520,301 1 16,085 16,085 1.4% 3.0%
030 13 106,689 1 1,581 1,581 7.6% 1.4%
008 54 377,593 1 7,098 7,098 1.8% 1.8%
018 24 171,264
022 25 8,884 1 433 433 4.0% 4.8%
035 9 42,043
041 13 112,355
列宽如下(以字符数计,包括空格):3,5,12,6,10,7,10,11,8,7。
解析这个的好方法是什么?我尝试过使用正则表达式来执行此操作,但在读入的第一行上显然失败了,因为我使用的表达式期望整行都有数据:
字符串模式 = @"^(?.{3})(?.{5})(?.{12})(?thirtyeightyninenumber>.{6})(?{10})(?.{7}( ?.{10})(?.{11})(?.{8})(?.{7})";
寻找一种好方法将其读入适当的变量,具体取决于该列是否有数据。我觉得我需要进行一堆
if
检查,但我希望有一个我没有想到的更好的方法。
感谢您的帮助。
顺便说一句 - 我正在使用 StreamReader 和 ReadLine 读取这些行。
TextFieldParser
专门用于读取这样的固定宽度/分隔文本文件。
它位于
Microsoft.VisualBasic.FileIO
命名空间中,但您仍然可以从 C# 中调用它。
添加对
Microsoft.VisualBasic
的引用,一个using Microsoft.VisualBasic.FileIO;
,那么代码如下所示:
TextFieldParser parser = new TextFieldParser(stream);
parser.TextFieldType = FieldType.FixedWidth;
parser.SetFieldWidths(3, 5, 12, 6, 10, 7, 10, 11, 8, 7);
while (!parser.EndOfData)
{
//Processing row
string[] fields = parser.ReadFields();
// Treat each field appropriately e.g. int.TryParse,
// remove the "%" then float.TryParse etc.
}
parser.Close();
编辑:也就是说,在反射器中查看,我认为如果您的缩短线没有全宽的空格,则此操作会失败。我不知道如何建议你解决这个问题;您可以预处理流以在每行插入任何缺失的空格吗?
不要为此使用正则表达式。 您知道列数和这些列的宽度,因此只需使用
String.Substring
和 String.Trim
:
string field1 = line.Substring(0, 5).Trim();
string field2 = line.Substring(5, 3).Trim();
string field3 = line.Substring(12, 8).Trim();
/* etc, etc */
有为此目的的开源 .Net 库:
https://github.com/borisdj/FixedWidthParserWriter/
PS我是作者。
只需根据 myDataString + new string(' ', 1000); 检查您的正则表达式(或其他任何内容);