対象文字列の処理
string[] lines = _msg.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
- CSVを処理するのにstreamが都合がいいのでstringを変換する
string[] lines = _msg.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines.Select((v, i) => new { v, i })) { using (Stream stream = new MemoryStream(Encoding.Default.GetBytes(line.v))) { // CSV処理 } }
CSVの処理
- stringのSplit(',')だと当然ながらカラムの中にカンマが出てきたらずれてしまうのでMicrosoft.VisualBasic.FileIO.TextFieldParserを使う。
- C#だけどVisualBasic・・・
using Microsoft.VisualBasic.FileIO; TextFieldParser parser = new TextFieldParser(stream, Encoding.GetEncoding("shift_jis")); parser.TextFieldType = FieldType.Delimited; parser.SetDelimiters(","); try { string[] csvData = parser.ReadFields(); // CSV処理 } catch (Exception e) { Console.WriteLine(e.Message); }
サンプル
- _msgには1行目にヘッダ、2行目以降にCSVデータが入ってくる想定。
- コンソールアプリから実行した別のコマンドの結果をパースする想定でEncodingを指定。
using Microsoft.VisualBasic.FileIO; _msg = FooMethod(); string[] lines = _msg.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines.Select((v, i) => new { v, i })) { using (Stream stream = new MemoryStream(Encoding.Default.GetBytes(line.v))) { TextFieldParser parser = new TextFieldParser(stream, Encoding.GetEncoding("shift_jis")); parser.TextFieldType = FieldType.Delimited; parser.SetDelimiters(","); try { if (line.i == 0) { string[] csvHeader = parser.ReadFields(); } else { string[] csvData = parser.ReadFields(); foreach (var item in csvData.Select((v, i) => new { v, i })) { Console.WriteLine(string.Format(" {0} : {1}", csvHeader[item.i], item.v)); } } } catch (Exception e) { Console.WriteLine(e.Message); } } }
.NETなのに、意外とシャキッと処理できないもんだよなぁ。