Java で CSV ファイルをカンマで区切る処理を、RFC4180 をムシして簡単に書こうとすると*1、String#split を使うことが多いかと思います。
しかし、String#split には以下のような罠が存在します。
public class SplitTest { public static void main(String args[]) { String stripped = "a,b,c,,,"; for ( String s : stripped.split(",") ) { System.out.print("[" + s + "]"); } System.out.println(); // [a][b][c] for ( String s : stripped.split(",", -1) ) { System.out.print("[" + s + "]"); } System.out.println(); // [a][b][c][][][] } }
コメントとして出力結果を示しましたが、String#split の第二引数に負値を渡さない場合、文字列 "a,b,c,,," の末尾にあるコンマの連続は、「まるで存在しなかったかのように」処理されることになります。実際に、stripped.split(",").length は 3 になってしまいます。これを防ぐには、第二引数に負値を与えなければなりません。
恥ずかしながら、String#split のこの仕様をぼくは今日はじめて知りました。(JavaDoc には書いてあるんですけどね)
しかし、どこかでこの仕様の覚えがあるなーと思っていたら、そういえばこれ、 Perl も同じでしたね…。
use strict; use warnings; my $stripped = "a,b,c,,,"; foreach ( split /,/ => $stripped ) { print "[$_]"; } print "\n"; # [a][b][c] foreach ( split /,/ => $stripped, -1 ) { print "[$_]"; } print "\n"; # [a][b][c][][][]
というわけなので、split には注意しましょうというお話でした。
*1:少なくとも、RFC4180 に定義された CSV を解析する処理としては正しくない