正規表現を使ってcsvから効率的に情報を取得する

投稿者: | 2011年7月12日

“2011/07/01,歯ブラシ,120円”
のようなcsvデータがあったとする。データは
年、月、日、品目、値段
の順に並んでいるものとする。
この内容を、

static class Data
{
	public final int Year;
	public final int Month;
	public final int Day;

	public final String Article;
	public final int Price;

	public Data(
		int year, 
		int month, 
		int day, 
		String article, 
		int price )
	{
		this.Year = year;
		this.Month = month;
		this.Day = day;
		this.Article = article;
		this.Price = price;
	}
}

のようなクラスのオブジェクトに変換したい。

このとき、正規表現を使うと効率的に情報を取得できる。
例えば、上の例のcsvの正規表現を
“([1-9][0-9]{3})/([0-2][1-9])/([0-3][0-9]),(.*),([1-9][0-9]*)円”
のように書いてみた。このように各部分をグループ化しておくことで、前方から
年、月、日、品目、値段
の順番で情報を取得できる。その様子をコードにすると、以下のような感じになるだろう。

public static Data parse(String string){
	Data result = null;

	Matcher matcher = 
		pattern.matcher("([1-9][0-9]{3})/([0-2][1-9])/([0-3][0-9]),(.*),([1-9][0-9]*)円");

	if( matcher.find()){
		result = new Data(
				Integer.parseInt(matcher.group(1)),
				Integer.parseInt(matcher.group(2)),
				Integer.parseInt(matcher.group(3)),
				matcher.group(4),
				Integer.parseInt(matcher.group(5)));
	}

	return result;
}

最後に、サンプルプログラムの全体を示す。

public class Main {

	/**
	 * 元csvデータ
	 */
	static final String[] csvData = new String[]{
	   "2011/07/01,歯ブラシ,120円",
	   "2011/07/01,タオル,250円",
	   "2011/07/01,スリッパ,800円",
	   "2011/07/01,リンゴ,500円"
    };

    /**
     * データを表現したクラス
     */
    static class Data
    {
    	public final int Year;
    	public final int Month;
    	public final int Day;

    	public final String Article;
    	public final int Price;

    	public Data(int year, int month, int day, String article, int price){
    		this.Year = year;
    		this.Month = month;
    		this.Day = day;
    		this.Article = article;
    		this.Price = price;
    	}

    	@Override
    	public String toString() {
    		return Year + "年" + Month + "月" + Day + "日" + " " + Article + " " + Price + "円";
    	}

    	private static final String REGEX =
    		"([1-9][0-9]{3})/([0-2][1-9])/([0-3][0-9]),(.*),([1-9][0-9]*)円";
        private static final Pattern pattern = Pattern.compile(REGEX);

        /**
         * 文字列からパースしてオブジェクトを作る
         * @param string
         * @return
         */
        public static Data parse(String string){
        	Data result = null;

        	Matcher matcher = pattern.matcher(string);
        	if( matcher.find()){
        		result = new Data(
        				Integer.parseInt(matcher.group(1)),
        				Integer.parseInt(matcher.group(2)),
        				Integer.parseInt(matcher.group(3)),
        				matcher.group(4),
        				Integer.parseInt(matcher.group(5)));
        	}

        	return result;
        }
    }

   /**
    * @param args
    */
   public static void main(String[] args) {

	   List<Data> dataList = new ArrayList<Data>();

       for( int i=0; i<csvData.length; i++ ){
    	   // csvの元データをDataオブジェクトに変換する
    	   Data data = Data.parse(csvData[i]);
    	   if( data != null){
    		   dataList.add(data);
    	   }
       }

       // 変換結果を表示
       for(Data d:dataList){
    	   System.out.println(d);
       }
   }
}

実行すると、以下のような結果となる。

2011年7月1日 歯ブラシ 120円
2011年7月1日 タオル 250円
2011年7月1日 スリッパ 800円
2011年7月1日 リンゴ 500円

このようにして、簡単にcsvから変換することができた。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です