2012-01-13 57 views
1

對於LINQ我完全不熟悉,我想了解它在解析文本文件中的用處,而不是使用諸如Perl或Ruby之類的腳本語言。我生成了一個由「CR」和「LF」分隔的長列表,我想創建一個.CSV文件來導出到僅包含前三行的Excel。例如:使用LINQ解析文本文件爲CSV

[CR][LF] 
     Field: Microsoft.VSTS.Build.FoundIn[CR][LF] 
     Name: Found In[CR][LF] 
     Type: String[CR][LF] 
     Use: Test project[CR][LF] 
     Indexed: False[CR][LF] 
     Reportable As: dimension[CR][LF] 
     Synchronizes Identity Name Changes: False[CR][LF] 
[CR][LF] 
     Field: Microsoft.VSTS.Build.IntegrationBuild[CR][LF] 
     Name: Integration Build[CR][LF] 
     Type: String[CR][LF] 
     Use: Test project[CR][LF] 
     Indexed: False[CR][LF] 
     Reportable As: dimension[CR][LF] 
     Synchronizes Identity Name Changes: False[CR][LF] 
[CR][LF] 

(不勝枚舉)

所需的輸出:

"Microsoft.VSTS.Build.FoundIn","Found In","String" 
"Microsoft.VSTS.Build.IntegrationBuild","Integration Build","String" 

我怎麼可以這樣寫LINQ中可能最簡單的方法?

回答

4

你只是在空行上的「部分」之間。只需通過將所有內容投入單獨的緩衝區的行,直到您到達空白行。當你這樣做時,處理緩衝區中的項目,清除它並重復。你不能真正在純LINQ 這個簡單的或優雅地做到這一點,所以不要強迫它餵它。

var buffer = new List<string>(); 
foreach (var line in File.ReadLines(pathToFile)) 
{ 
    if (String.IsNullOrWhitespace(line)) 
    { 
     ProcessSection(outputFile, buffer); 
     buffer.Clear(); // or create a new one 
    } 
    else 
    { 
     buffer.Add(line); 
    } 
} 

static void ProcessSection(StreamWriter outputFile, List<string> buffer) 
{ 
    if (buffer.Count == 0) return; 
    var contents = buffer.Take(3) 
     .Select(line => String.Format("\"{0}\"", line.Substring(line.IndexOf(": ") + 2))); 
    outputFile.WriteLine(String.Join(",", contents)); 
} 
+0

不知道關於'File.EnumerateLines' - 這是非常整潔。 – 2012-01-13 18:40:10

+0

'System.IO.File'不包含.NET 4.0中的'EnumerateLines'! – 2012-01-13 18:44:37

+0

@JFB:哎呀,對不起,錯名。這應該是'ReadLines()'。 – 2012-01-13 18:47:25