@Test public void parse() { testOneLine("aa, bb", "aa", " bb"); testOneLine("aa, bb,", "aa", " bb", ""); test("aa, bb\r\ncc,\"dd", 2, 1, "cc", "dd"); }
public static List<List<String>> parse(String source) { ArrayList<List<String>> result = new ArrayList<>(); ArrayList<String> record = new ArrayList<>(); State state = State.START; field.setLength(0); for (int i = 0; i < source.length(); i++) { char c = source.charAt(i); switch (state) { case START: switch (c) { case comma: record.add(""); break; case quote: field.setLength(0); state = State.QUOTE; break; case cr: field.setLength(0); state = State.CR; break; default: field.setLength(0); field.append(c); state = State.NO_QUOTE; break; } break; case NO_QUOTE: switch (c) { case comma: addField(record, field); state = State.START; break; case cr: state = State.CR; break; default: field.append(c); break; } break; case QUOTE: switch (c) { case quote: state = State.QUOTE2; break; default: field.append(c); break; } break; case QUOTE2: switch (c) { case comma: addField(record, field); state = State.START; break; case quote: field.append(quote); state = State.QUOTE; break; case cr: state = State.CR; break; default: field.append(c); state = State.NO_QUOTE; break; } break; case CR: switch (c) { case comma: field.append(cr); addField(record, field); state = State.START; break; case lf: addField(record, field); addRecord(result, record); record = new ArrayList<>(record.size()); state = State.START; break; default: field.append(cr); field.append(c); state = State.NO_QUOTE; break; } break; } } switch (state) { case START: if (!record.isEmpty()) { record.add(""); addRecord(result, record); } break; case CR: field.append(cr); addField(record, field); addRecord(result, record); break; default: addField(record, field); addRecord(result, record); break; } result.trimToSize(); return result; }
CSVParser { public static List<List<String>> parse(String source) { ArrayList<List<String>> result = new ArrayList<>(); ArrayList<String> record = new ArrayList<>(); State state = State.START; field.setLength(0); for (int i = 0; i < source.length(); i++) { char c = source.charAt(i); switch (state) { case START: switch (c) { case comma: record.add(""); break; case quote: field.setLength(0); state = State.QUOTE; break; case cr: field.setLength(0); state = State.CR; break; default: field.setLength(0); field.append(c); state = State.NO_QUOTE; break; } break; case NO_QUOTE: switch (c) { case comma: addField(record, field); state = State.START; break; case cr: state = State.CR; break; default: field.append(c); break; } break; case QUOTE: switch (c) { case quote: state = State.QUOTE2; break; default: field.append(c); break; } break; case QUOTE2: switch (c) { case comma: addField(record, field); state = State.START; break; case quote: field.append(quote); state = State.QUOTE; break; case cr: state = State.CR; break; default: field.append(c); state = State.NO_QUOTE; break; } break; case CR: switch (c) { case comma: field.append(cr); addField(record, field); state = State.START; break; case lf: addField(record, field); addRecord(result, record); record = new ArrayList<>(record.size()); state = State.START; break; default: field.append(cr); field.append(c); state = State.NO_QUOTE; break; } break; } } switch (state) { case START: if (!record.isEmpty()) { record.add(""); addRecord(result, record); } break; case CR: field.append(cr); addField(record, field); addRecord(result, record); break; default: addField(record, field); addRecord(result, record); break; } result.trimToSize(); return result; } }
CSVParser { public static List<List<String>> parse(String source) { ArrayList<List<String>> result = new ArrayList<>(); ArrayList<String> record = new ArrayList<>(); State state = State.START; field.setLength(0); for (int i = 0; i < source.length(); i++) { char c = source.charAt(i); switch (state) { case START: switch (c) { case comma: record.add(""); break; case quote: field.setLength(0); state = State.QUOTE; break; case cr: field.setLength(0); state = State.CR; break; default: field.setLength(0); field.append(c); state = State.NO_QUOTE; break; } break; case NO_QUOTE: switch (c) { case comma: addField(record, field); state = State.START; break; case cr: state = State.CR; break; default: field.append(c); break; } break; case QUOTE: switch (c) { case quote: state = State.QUOTE2; break; default: field.append(c); break; } break; case QUOTE2: switch (c) { case comma: addField(record, field); state = State.START; break; case quote: field.append(quote); state = State.QUOTE; break; case cr: state = State.CR; break; default: field.append(c); state = State.NO_QUOTE; break; } break; case CR: switch (c) { case comma: field.append(cr); addField(record, field); state = State.START; break; case lf: addField(record, field); addRecord(result, record); record = new ArrayList<>(record.size()); state = State.START; break; default: field.append(cr); field.append(c); state = State.NO_QUOTE; break; } break; } } switch (state) { case START: if (!record.isEmpty()) { record.add(""); addRecord(result, record); } break; case CR: field.append(cr); addField(record, field); addRecord(result, record); break; default: addField(record, field); addRecord(result, record); break; } result.trimToSize(); return result; }  }
CSVParser { public static List<List<String>> parse(String source) { ArrayList<List<String>> result = new ArrayList<>(); ArrayList<String> record = new ArrayList<>(); State state = State.START; field.setLength(0); for (int i = 0; i < source.length(); i++) { char c = source.charAt(i); switch (state) { case START: switch (c) { case comma: record.add(""); break; case quote: field.setLength(0); state = State.QUOTE; break; case cr: field.setLength(0); state = State.CR; break; default: field.setLength(0); field.append(c); state = State.NO_QUOTE; break; } break; case NO_QUOTE: switch (c) { case comma: addField(record, field); state = State.START; break; case cr: state = State.CR; break; default: field.append(c); break; } break; case QUOTE: switch (c) { case quote: state = State.QUOTE2; break; default: field.append(c); break; } break; case QUOTE2: switch (c) { case comma: addField(record, field); state = State.START; break; case quote: field.append(quote); state = State.QUOTE; break; case cr: state = State.CR; break; default: field.append(c); state = State.NO_QUOTE; break; } break; case CR: switch (c) { case comma: field.append(cr); addField(record, field); state = State.START; break; case lf: addField(record, field); addRecord(result, record); record = new ArrayList<>(record.size()); state = State.START; break; default: field.append(cr); field.append(c); state = State.NO_QUOTE; break; } break; } } switch (state) { case START: if (!record.isEmpty()) { record.add(""); addRecord(result, record); } break; case CR: field.append(cr); addField(record, field); addRecord(result, record); break; default: addField(record, field); addRecord(result, record); break; } result.trimToSize(); return result; }  static List<List<String>> readFromFile(Path path, String encoding); static List<List<String>> parse(String source); static boolean isEmptyRecord(List<String> record); static boolean parseBoolean(String s); static float parseFloat(String s); static int parseInt(String s); static long parseLong(String s); }
CSVParser { public static List<List<String>> parse(String source) { ArrayList<List<String>> result = new ArrayList<>(); ArrayList<String> record = new ArrayList<>(); State state = State.START; field.setLength(0); for (int i = 0; i < source.length(); i++) { char c = source.charAt(i); switch (state) { case START: switch (c) { case comma: record.add(""); break; case quote: field.setLength(0); state = State.QUOTE; break; case cr: field.setLength(0); state = State.CR; break; default: field.setLength(0); field.append(c); state = State.NO_QUOTE; break; } break; case NO_QUOTE: switch (c) { case comma: addField(record, field); state = State.START; break; case cr: state = State.CR; break; default: field.append(c); break; } break; case QUOTE: switch (c) { case quote: state = State.QUOTE2; break; default: field.append(c); break; } break; case QUOTE2: switch (c) { case comma: addField(record, field); state = State.START; break; case quote: field.append(quote); state = State.QUOTE; break; case cr: state = State.CR; break; default: field.append(c); state = State.NO_QUOTE; break; } break; case CR: switch (c) { case comma: field.append(cr); addField(record, field); state = State.START; break; case lf: addField(record, field); addRecord(result, record); record = new ArrayList<>(record.size()); state = State.START; break; default: field.append(cr); field.append(c); state = State.NO_QUOTE; break; } break; } } switch (state) { case START: if (!record.isEmpty()) { record.add(""); addRecord(result, record); } break; case CR: field.append(cr); addField(record, field); addRecord(result, record); break; default: addField(record, field); addRecord(result, record); break; } result.trimToSize(); return result; }  static List<List<String>> readFromFile(Path path, String encoding); static List<List<String>> parse(String source); static boolean isEmptyRecord(List<String> record); static boolean parseBoolean(String s); static float parseFloat(String s); static int parseInt(String s); static long parseLong(String s);  }