RFC4180準拠、カンマ区切り、括り文字はダブルクォーテーションの1行分の文字列
から、List<String> に変換する原始的なロジックで書いたメソッドを
ある目的の為に書きました。
Java8以上のコードではなく、見にくくても敢えて原始的なロジックで書いています。
",,"や、”, ,” のように、カンマ区切り並んだ場合は、””空文字列をListに詰め込みます。
import java.text.ParseException; import java.util.ArrayList; import java.util.Collections; import java.util.List;
public static List<String> csvlineToList(String line) { char DELIMITER = ','; char CARRIAGE_RETURN = '\r'; char NEWLINE = '\n'; char DOUBLE_QUOTE = '"'; if (line==null || line.length()==0){ return Collections.emptyList(); } List<String> tokens = new ArrayList<String>(); StringBuilder tokenBuf = new StringBuilder(); boolean insideDoubleQuote = false; boolean isDoubleQuoteEscapeActive = false; StringBuilder wspBuf = new StringBuilder(); for(int ii=0; ii < line.length(); ii++){ final char ch = line.charAt(ii); if (ch==CARRIAGE_RETURN || ch==NEWLINE){ if (insideDoubleQuote){ tokenBuf.append(ch); }else{ throw new RuntimeException("unquoted " + (ch=='\n' ? "newline" : "carriage return") + " found at position #" + (ii+1)); } }else if(ch==DOUBLE_QUOTE){ if (insideDoubleQuote){ if (isDoubleQuoteEscapeActive){ tokenBuf.append(ch); isDoubleQuoteEscapeActive = false; }else if(((ii+1) < line.length()) && line.charAt(ii+1)==DOUBLE_QUOTE){ isDoubleQuoteEscapeActive = true; }else{ insideDoubleQuote = false; } }else{ insideDoubleQuote = true; if (wspBuf.length() != 0){ if (tokenBuf.length() != 0){ tokenBuf.append(wspBuf); } wspBuf.delete(0, wspBuf.length()); } } }else{ if (insideDoubleQuote){ tokenBuf.append(ch); }else{ if (ch==DELIMITER){ tokens.add(tokenBuf.toString()); tokenBuf.delete(0, tokenBuf.length()); wspBuf.delete(0, wspBuf.length()); }else if(Character.isWhitespace(ch)){ wspBuf.append(ch); }else{ if (wspBuf.length() != 0){ if (tokenBuf.length() != 0){ tokenBuf.append(wspBuf); } wspBuf.delete(0, wspBuf.length()); } tokenBuf.append(ch); } } } } if (insideDoubleQuote){ throw new RuntimeException("terminating double quote not found"); } tokens.add(tokenBuf.toString()); return tokens; }