2011-09-14 54 views
1

我是C#開發新手。我需要解析每行包含多行數據的巨大文本文件。輸出將是一個CSV文件。解析文本文件爲CSV C#

文件的格式遵循以下模式:

 
Acronym: TIFFE 
Name of proposal: Thermal Systems Integration for Fuel Economy 
Contract number: 233826 
Instrument: CP – FP 
# 
Acronym: STREAMLINE 
Name of proposal: Strategic Research For Innovative Marine Propulsion Concepts 
Contract number: 233896 
Instrument: CP – FP 

其中#代表的新紀錄。現在這個文本文件中有數百個'記錄'。我希望能夠使用Acronym,Proposal Name等列以及包含每條記錄實際數據的行將所有內容解析爲CSV。

有沒有最好的方法如何嘗試這個?

我猜我必須在將數據解析爲CSV之前將數據解析爲中間數據 - 就像DataTable一樣。

回答

3

這個簡單的LINQ語句解析輸入文件到記錄的序列,並寫入以CSV格式輸出文件的每個記錄(假設領域的每個記錄的數量和順序是一樣的):

File.WriteAllLines("output.csv", File 
    .ReadLines("input.txt") 
    .GroupDelimited(line => line == "#") 
    .Select(g => string.Join(",", g 
     .Select(line => string.Join(line 
      .Substring(line.IndexOf(": ") + 1) 
      .Trim() 
      .Replace("\"", "\"\""), "\"", "\""))))); 

輸出:

 
"TIFFE","Thermal Systems Integration for Fuel Economy","233826","CP – FP" 
"STREAMLINE","Strategic Research For Innovative Marine Propulsion Concepts","233896","CP – FP" 

Helper方法:

static IEnumerable<IEnumerable<T>> GroupDelimited<T>(
    this IEnumerable<T> source, Func<T, bool> delimiter) 
{ 
    var g = new List<T>(); 
    foreach (var x in source) 
    { 
     if (delimiter(x)) 
     { 
      yield return g; 
      g = new List<T>(); 
     } 
     else 
     { 
      g.Add(x); 
     } 
    } 
    yield return g; 
} 
+0

現在這是一段很長的代碼! – Brad

+0

Yikes! +1,以提高可讀性:) –

+0

我收到以下錯誤:'System.Collections.Generic.IEnumerable '不包含'GroupDelimited'的定義,也沒有接受'System.Collections'類型的第一個參數的擴展方法'GroupDelimited'。可以找到'Generic.IEnumerable '(你是否缺少使用指令或程序集引用?)\t c:\ users \ user \ documents \ visual studio 2010 \ Projects \ Fileparser \ Fileparser \ Program.cs –

1

你不necessarilly必須分析這一個DataTable第一。當您讀取源文件時,您可以直接StreamWrite CSV。顯然,如果源的每個記錄中的字段的順序和出現是一致的,則會更容易。

但是,對於任何與CSV有關的事情,您應該考慮使用專門的庫。像FileHelpers一樣。

+0

+1:專門的庫會正確處理逗號和雙引號字符(如果它們出現在數據中,則換行符;如果一個雙換行符表示一個字段分隔符,就像它在你的例子中出現的那樣,文件格式_may_支持換行符作爲數據)。 –