3

私のプログラムは、「Timestamp」、「LiveStandby」、「Total1」、「Total2」、「Total3」などの下に、このような行が何千行もあるファイルを読み取ります。各行は異なります。分割する最良の方法は何ですか、「」を削除し、値をリストに入れます

これは私が持っているものです

 while ((line = file.ReadLine()) != null)
  {
     List<string> title_list = new List<string>(line.Split(',')); 
  }

上記の手順では、引用符の削除がまだありません。私は foreach を行うことができますが、List と Split を 1 行で行うという目的に反しています。それを行うための最善かつスマートな方法は何ですか?

4

5 に答える 5

4

私の意見では、FileHelpersなどのCSVを解析するライブラリを使用するのが最善の方法です。

具体的には、あなたの場合、これは FileHelpers ライブラリを使用したソリューションになります。

レコードの構造を記述するクラスを定義します。

[DelimitedRecord(",")]
public class MyDataRecord
{
    [FieldQuoted('"')]
    public string TimeStamp;
    [FieldQuoted('"')]
    public string LiveStandby;
    [FieldQuoted('"')]
    public string Total1;
    [FieldQuoted('"')]
    public string Total2;
    [FieldQuoted('"')]
    public string Total3;
}

このコードを使用して、ファイル全体を解析します。

var csvEngine = new FileHelperEngine<MyDataRecord>(Encoding.UTF8)
    { 
        Options = { IgnoreFirstLines = 1, IgnoreEmptyLines = true }
    };

var parsedItems = csvEngine.ReadFile(@"D:\myfile.csv");

このコードは説明用であり、コンパイル/実行していないことに注意してください。ただし、ライブラリは非常に簡単に使用でき、Web サイトには優れた例とドキュメントがあります。

于 2012-04-26T20:44:39.187 に答える
2

これを少し明確にします。予測可能な形式のユーザー形式のファイルがある場合(つまり、ユーザーがEXCELまたは同様のプログラムからデータを生成した場合)、十分にテストされた既存のパーサーを使用する方がはるかに優れています。

次のようなシナリオは、手動解析で問題が発生するほんの一例です。

"column 1", 2, 0104400, $1,300, "This is an interestion question, he said"

..そして、エスケープ、ファイル形式など、自分でロールするのに頭痛の種になる可能性のあるものが他にもあります。

その場合は、違いを生む可能性があるため、行ごとの列の違いを許容できるものを確実に入手してください。

一方、システムで生成されたファイルで一般的なデータに何が入っているかがわかっている場合は、CSVパーサーを使用すると解決するよりも多くの問題が発生します。たとえば、最初の部分が固定されて強く型付けできるシナリオを扱ってきましたが、次の部分はそうではありません。これは、レガシーデータベースから固定幅のシナリオでフラットファイルデータを解析している場合にも発生する可能性があります。csvソリューションは、私たちが望まない仮定を立てており、それらの多くの場合、適切なソリューションではありません。

その場合、コンマで分割した後に引用符を削除したいだけの場合は、linqを少し試してください。これを拡張して、気になる特定の文字を置き換えることもできます。

line.Split(',').Select(i => i.Replace("\"", "")).ToArray()

それがすべての矛盾するアドバイスを解決することを願っています。

于 2012-04-26T20:46:12.227 に答える
2

このように単純に保つと、うまくいくはずです。

List<string> strings = new List<string>();
while ((line = file.ReadLine()) != null) 
    string.AddRange(line.Replace("\"").split(',').AsEnumerable());
于 2012-04-26T20:46:55.403 に答える
1

機能を使用できますArray.ConvertAll()

string line = "\"Timestamp\",\"LiveStandby\",\"Total1\",\"Total2\",\"Total3\"";

var list = new List<String>(Array.ConvertAll(line.Split(','), x=> x.Replace("\"","")));
于 2012-04-26T20:53:23.500 に答える
0

最初に置換を実行してから、リストに分割します。これがReplaceを使用したコードです。

while ((line = file.ReadLine()) != null)   
{      
  List<string> title_list = new List<string>(line.Replace("\"", "").Split(','));    
}

ただし、すべてのリストを保持する変数が必要になるため、AddRange() の使用を検討してください。

于 2012-04-26T20:56:14.870 に答える