CSV Parser

 

public class Solution {
  public static void main(String[] args) {
    System.out.println(parseCSV(
        "\"Kobe Bryant, 2020\",AAA, McDonald\"\"\"\"s, \"McDonald\"\"s\",\"\",asdf\"\"\"gh&$#^% \"\"sdfhjn,%$#^%\"\"\""));
    System.out.println(parseCSV(
        "\"Kobe Bryant, 2020\",AAA, McDonald\"\"\"\"s, \"McDonald\"\"s\",\"\",asdf\"\"\"gh&$#^% \"\"sdfhjn,%$#^%\"\"\""));
    System.out.println(parseCSV(
        "\"Kobe Bryant, 2020\",AAA, McDonald\"\"\"\"s, \"McDonald\"\"s\",\"\",asdf\"\"\"gh&$#^% \"\"sdfhjn,%$#^%\"\"\""));
  }

  public static String parseCSV(String str) {
    List<String> list = new ArrayList<>();

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < str.length(); ++i) {
      char c = str.charAt(i);
      if (c == '"') {
        Object[] ret = consumeCharsWithinQuotes(str, i + 1);
        String withinQuotes = (String) ret[0];
        i = (Integer) ret[1]; //returned position points to the ending quote
        sb.append(withinQuotes);
      } else if (c == ',') {
        list.add(sb.toString());
        sb.setLength(0);
      } else {
        sb.append(c);
      }
    }
    //add the last item to list
    list.add(sb.toString());
    return String.join(" | ", list);
  }

  private static Object[] consumeCharsWithinQuotes(String str, int start) {
    StringBuilder sb = new StringBuilder();
    for (int i = start; i < str.length(); ++i) {
      char c = str.charAt(i);
      if (c == '"') {
        if (i == str.length() - 1) {
          //this is the ending quote
          return new Object[]{sb.toString(), i};
        }
        char nextChar = str.charAt(i + 1);
        if (nextChar == '"') {
          //this is an escaped quote
          sb.append('"');
          ++i;
        } else {
          //this is an internal ending quote
          return new Object[]{sb.toString(), i};
        }
      } else {
        sb.append(c);
      }
    }

    return null;
  }
}

 

posted @ 2021-01-14 02:32  新一代的天皇巨星  阅读(1080)  评论(0编辑  收藏  举报