テキストファイルをCSV形式に変換するツールを作ってみた

スマホでデータを入力するときにどうしてますか? 私は、フィールドの区切りを改行、レコードの区切りを空行にする、という感じにテキストエディタに入力してテキストファイルを作っています。 例えばこんな感じです。

目次

  1. 処理の流れ
  2. コード
  3. 動かしてみた
  4. 課題
testa1
0123
testa2

testb1
0,123
testb2

testc1
0123
test"c2

人間にはわかりやすいデータなのですが、Excelで処理するにはちょっと使いにくい形式です。 そこで、C#でこのデータをCSVに変換するプログラムを作ってみました。 テキストデータをパイプで入力すると、コンソールにCSVデータを出力するプログラムです。 CSV形式の書式については、別の記事を参照してください。

処理の流れ

  1. コンソールから1行読み込む。

  2. 空行であれば、レコードの読み込みが終わったとして、そのレコードを出力する。

  3. 空行でなければ、フィールドを1つ読み込んだとして、次項の文字列に対する処理をする。

  4. フィールドにダブルクォーテーションが含まれていれば、エスケープしてデータの前後にダブルクォーテーションを追加する。カンマが含まれていれば、データの前後にダブルクォーテーションを追加する。

  5. 入力が終わるまで1~4を繰り返す。

コンソールからパイプを使って入力する手順はこちらを参照してください。 文字列にダブルクォーテーションやカンマが含まれているか調べる手順はこちらを参照してください。 文字列の置換についてはこちらを参照してください。

コード

コードはこんな感じです。 if文のネストがすごい。

using System;
using System.IO;
using System.Text.RegularExpressions;

namespace text2csv
{
    class Program
    {
        static void Main(string[] args)
        {
            TextReader reader = Console.In;

            string textOut = string.Empty; // 出力用変数
            while (reader.Peek() >= 0)
            {
                string textRead = reader.ReadLine(); // 1行読み込む

                if (textRead.Length < 1)
                {
                    // 空行の場合は出力して、出力用変数をリセット
                    Console.WriteLine(textOut);
                    textOut = string.Empty;
                }
                else
                {
                    // 空行でない場合
                    if (textRead.IndexOf("\"") > 0)
                    {
                        // "がある場合は""に置換して、前後に"を付け足す
                        string str = Regex.Replace(textRead, "\"", "\"\"");
                        textRead = "\"" + str + "\"";
                    }
                    else if (textRead.IndexOf(",") > 0)
                    {
                        // "が無くても,がある場合は前後に"を付け足す
                        textRead = "\"" + textRead + "\"";
                    }

                    if (textOut.Length < 1)
                    {
                        // 出力用変数が空の場合
                        textOut = textRead;
                    }
                    else
                    {
                        // 出力用変数にすでにデータが入っている場合
                        textOut = textOut + "," + textRead;
                    }
                }
            }
            Console.WriteLine(textOut); // 出力
        }
    }
}

動かしてみた

早速コンソールで動かしてみました。 image0 パイプの方はCSVになってますね。 Excelで開いてみると、こんな感じです。 image1

課題

スマホがAndroidなので、テキストファイルの文字コードをUTF-8 BOM無しに、改行コードをLFにしていたのですが、このままですとコンソールで文字化けします。 コンソールをUTF-8に切り替えて変換するとうまくいくのですが、そうするとExcelに読みこんだときに文字化けします。 プログラム内部ではUTF-16で処理しているのでしょうから、そろそろBOM無しUTF-8も自動判別して読み込んでもらえないでしょうか。Excelさん。

公開日

広告