2012-04-26 4 views
3

私のプログラムは、以下のような何千もの行を持つファイルを読み取ります "タイムスタンプ"、 "LiveStandby"、 "Total1"、 "Total2"、 "Total3 」など。 各行はによって分割するための最良の方法は何 異なり、および削除 『これは私が文字列内の文字の複数の出現を削除するスマートな方法

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

を持っているものである』と同様に、リスト内の値を入れ

を上のステップではまだ引用符の削除がありません。私はforeachをすることができますが、ちょうど1行でListとSplitを持つという目的を打ち負かしています。それを行うための最高のスマートな方法は何ですか?

+1

2つの単語:正規表現 –

+0

@Al - これはどこに適用すればよいですか?私はスプリットを過負荷にすることはできないと思いますか? –

+8

"問題に直面したときには、「わかっています、私は正規表現を使用します。今、彼らには2つの問題があります。 - Jamie Zawinski – zimdanen

答えて

2

簡単な、これは動作するはずのようにそれを維持する:

List<string> strings = new List<string>(); 
while ((line = file.ReadLine()) != null) 
    string.AddRange(line.Replace("\"").split(',').AsEnumerable()); 
+0

@naspinski - ToEnumerableは利用できませんか?私は何かを欠いている? –

+0

using System.Linq; – zimdanen

+0

私はSystem.Linqを持っています。まだ使用できません。.NET3.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"); 

このコードは単に例示のためのものであると私はそれを実行/コンパイルされていないことに注意してください。しかし、このライブラリは使用するのが簡単で、ウェブサイトには良い例とドキュメントがあります。

+1

OPはそれが普通のCSVファイルだとは決して言わなかった。彼は、それぞれの線が違うと言っていました。これは、1行目に10文字列、2行目に20文字列などを意味する可能性があります。 – hatchet

+0

@hatchet OPは "CSV"とは言わなかったのは事実ですが、提示されたケースはCSVファイルに非常に似ています。 "すべての行が違う"とは、各行に新しい値があることや、 '' ''が必ずしも並び替えられないことを意味するかもしれません。 – GolfWolf

+0

@Andrew:私はここでRegexの解決策を見ることができません。本当に基本的で良いものではないソリューションを交換/分割するだけです。正規表現はより良くできますが、遅いです。 –

2

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

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

、より自分自身のロールのための頭痛することができエスケープ、ファイル形式などであります。以下のような

シナリオは、手動解析が持つ問題を抱えているだろうというほんの一例です。

これを実行すると、行ごとの違いが異なる可能性のあるものを確実に取得できます。

一方で、あなたはシステムで一般的であるデータの中に何が起こっているのか知っている、場合

は、生成され、その後、CSVパーサを使用してファイルは、彼らが解決するよりも多くの問題が発生します。たとえば、最初の部分が修正され強く型付けされるシナリオを扱っていますが、後続の部分は並んでいない部分があります。これは、レガシーデータベースから固定幅のシナリオでフラットファイルデータを解析する場合にも発生します。 csvソリューションは、私たちが望んでいない仮定を作成し、そうしたケースの多くで適切な解決策ではありません。

この場合、コンマで区切って引用符を取り除きたい場合は、linqを少し試してみてください。これは、あなたが心配している特定の文字を置き換えるように拡張することもできます。

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

矛盾するすべてのアドバイスをクリアします。

+0

Andrewのおかげで、私は彼が何をしているのか知っていたと思っていました。私は、一方で私のCSVパーサーヘルパーを書くことができましたが、彼は何も覚えていませんでしたか? – Gats

+0

cvパーサを使用することは有効な提案ですが、探している回答ではありません。 – Gats

+0

いいですよ。この援助を考慮に入れて答えが更新されました。事実は私がその質問が文字通りであると仮定していたが、質問の中で彼が指定していないシナリオを扱っていると仮定した人もいた。どちらも正しいかもしれません...それがクリアされたと考えてください。彼の質問にCSVの言及はありません。 – Gats

1

あなたはArray.ConvertAll()機能を使用することができます。

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

var list = new List<String>(Array.ConvertAll(line.Split(','), x=> x.Replace("\"",""))); 
0

最初に置換を実行してから、リストに分割します。ここにあなたのコードが置き換えられます。

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

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

関連する問題