5

列にフォーマットされたテキストレポートを解析しようとしています。各列は、固定長で右寄せされているように見えます。各行について、すべての列が使用されているわけではない場合があります。その場合、行の各列を揃えるためにスペースが使用されているように見えます。入力例:

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を使用して行を読んでいます。

4

3 に答える 3

8

TextFieldParserこのような固定幅/区切りテキストファイルを読み取るために特別に意図された利用可能なものがあります。

名前空間にありMicrosoft.VisualBasic.FileIOますが、C#から呼び出すことができます。

Microsoft.VisualBasic、aへの参照を追加すると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();

編集:そうは言っても、Reflectorを見ると、短縮された線に全幅に相当するスペースがない場合、これは失敗すると思います。これを修正する方法がわかりません。ストリームを前処理して、行ごとに不足しているスペースを挿入できますか?

于 2012-09-20T14:48:09.097 に答える
6

これには正規表現を使用しないでください。列の数とそれらの列の幅がわかっているので、とを使用するだけ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 */
于 2012-09-20T14:43:50.567 に答える
-1

myDataString + new string(''、1000);に対して正規表現(またはその他)をチェックするだけです。

于 2014-10-27T16:21:43.593 に答える