2012-11-29 23 views
2

我在這一塊上挖了很多東西,沒有發現我一直在尋找。一行一行地分析和存儲是否符合標準,否則忽略

輸入:多個(數百,偶爾數以千計)的ASCII文本行,範圍從97個字符到500個以上。我想保留這些數據的標準純粹包含在前3個字符中(總是數字 - 任意值100,200和300是我感興趣的)。

所需的輸出僅爲以100,200或300開始的輸出,其餘的我可以忽略。

這是我作爲我的StreamReader,目前輸出到控制檯:

using System; 
using System.Collections.Generic; 
using System.IO; 

class Program 
{ 
public void Do 
{ 

    // Read in a file line-by-line, and store in a List. 

    List<string> list = new List<string>(); 
    using (StreamReader reader = new StreamReader("File.dat")) 
    { 
     string line; 
     while ((line = reader.ReadLine()) != null) 
     { 
      list.Add(line); // Add to list. 
      Console.WriteLine(line); // Write to console. 
     // Console.ReadLine(); 
     } 
    } 
} 
} 

我希望把在這樣一行

IF { 
FIRST3CHAR != (100,200,300) } 
then skip, 

,但我不知道該如何定義FIRST3CHAR類。這是將在原始數據上完成的唯一過濾器。

之後,我會根據其中包含的其他標準分析這個過濾的數據集,但我會在請求任何幫助之前親自給我一個鏡頭。

回答

1

是否有一個原因,你不只是將這個條件添加到你的循環?

while ((line = reader.ReadLine()) != null) 
{ 
    var beginning = line.Substring(0, 3); 
    if(beginning != "100" && beginning != "200" && beginning != "300") 
     continue; 
    list.Add(line); // Add to list. 
    Console.WriteLine(line); // Write to console. 
} 
2

最簡單地說:

if(line.StartsWith("100") || line.StartsWith("200") || line.StartsWith("300")) 
{ 
    list.Add(line); // Add to list. 
    Console.WriteLine(line); // Write to console. 
} 

如果該文件是巨大的(如,幾十萬行),它也可能是值得考慮的執行它作爲一個迭代器塊。但「開始」測試非常簡單。

如果你需要更多的靈活性,我會考慮一個正則表達式;例如:

static readonly Regex re = new Regex("^[012]00", RegexOptions.Compiled); 

... 
while (...) 
{ 
    if(re.IsMatch(line)) 
    { 
     list.Add(line); // Add to list. 
     Console.WriteLine(line); // Write to console. 
    } 
} 
+0

你也可以考慮爲輸出填充一個StringBuilder,如果沒有必要實時使用 –

+0

@trippino我們不知道OP使用列表是什麼;我不認爲stringbuilder適用於這裏。控制檯看起來像一個UI示蹤對我來說 - 可能很好,保持「按原樣」 –

+0

是的,這只是一個提示,更快速地調試 –

5

此代碼是更具可讀性和你想要做什麼:

var allowedNumbers = new[]{ "100", "200", "300" }; 
IEnumerable<String> lines = File 
        .ReadLines("File.dat") 
        .Where(l => allowedNumbers.Any(num => l.StartsWith(num))); 

現在你可以列舉例如線路用foreach

foreach(string line in lines) 
{ 
    Console.WriteLine(line); // Write to console. 
} 

既然你想無論如何添加這些行到List<string>,您可以使用Enumerable.ToList而不是foreach

List<string> list = lines.ToList(); 
+0

甜蜜的解決方案,但潛在的瓶頸。 – Leri

+2

@PLB:你在哪裏看到瓶頸?請注意['ReadLines'](http://msdn.microsoft.com/zh-cn/library/dd383503.aspx)在返回結果之前不會將整個文件讀入內存。有關更多信息,請參閱其文檔的*備註*部分。 –

+0

@DanielHilgarth'Where將迭代讀取行,'any'將迭代'allowedMembers'。雖然這可以在循環中完成。我並不是說這是一個糟糕的解決方案。不要誤解我的意思。 :) – Leri