Парсер CSV в JAVA, двойные кавычки в строке (SuperCSV, OpenCSV)

весь день я искал, как решить эту проблему, и ничего... Я хочу написать функцию, которая преобразует файл CSV в набор списков (строк). Вот эта функция:

public Collection<? extends List<String>> parse() throws IOException {
    Collection<List<String>> collectionOfLists = new ArrayList<List<String>>();
    CsvListReader parser = new CsvListReader(Files.newBufferedReader(pathToFile, StandardCharsets.UTF_8), CsvPreference.EXCEL_PREFERENCE);

    List<String> row;
    while( (row = parser.read()) != null)
        collectionOfLists.add(row);

    return collectionOfLists;
}

public static String toString(Collection<? extends List<String>> csv) {
    StringBuilder builder = new StringBuilder();
    for(List<String> l : csv) {
        for(String s : l)
            builder.append(s).append(',');
        if(builder.length() > 0)
            builder.setCharAt(builder.length()-1,'\n');
    }
    return builder.toString();
}

Но напр. для этого ввода:

id, name, city, age
1,"Bob",London,12

Вывод для toString(parse()):

id, name, city, age
1,Bob,London,12 

вместо того же, что и ввод:/ Что я могу сделать, что строки содержат \" (кавычки)? Пожалуйста, помогите мне.


person user3521479    schedule 10.04.2014    source источник
comment
эээ... если вы хотите написать свой собственный, почему SuperCSV, OpenCSV в заголовке вопроса?   -  person Leo    schedule 11.04.2014
comment
Похоже, что библиотека удаляет "".   -  person Sotirios Delimanolis    schedule 11.04.2014
comment
потому что я пытался использовать эти классы, но не нашел решения   -  person user3521479    schedule 11.04.2014
comment
В javadoc, вероятно, есть то, что вам нужно.   -  person Sotirios Delimanolis    schedule 11.04.2014
comment
Я просматривал его несколько раз...   -  person user3521479    schedule 11.04.2014


Ответы (3)


Из вашего вопроса не ясно, спрашиваете ли вы....

<сильный>1. Мои данные содержат кавычки. Почему они удаляются?

В этом случае я бы указал вам на спецификацию CSV, так как ваш файл CSV не экранирован надлежащим образом. , поэтому эти кавычки на самом деле не являются частью ваших данных.

Так должно быть

1,""Bob"",London,12

нет

1,"Bob",London,12

<сильный>2. Как применять кавычки при написании (даже если данные не содержат запятых, кавычек и т. д.)?

По умолчанию Super CSV экранируется только в случае необходимости (поле содержит запятую, двойную кавычку или новую строку).

Если вы действительно хотите включить кавычки, вы можете настроить Super CSV с режимом кавычек.

Например, вы всегда можете заключить в кавычки столбец имени в своем примере со следующими настройками:

private static final CsvPreference ALWAYS_QUOTE_NAME_COL = 
    new CsvPreference.Builder(CsvPreference.STANDARD_PREFERENCE)
    .useQuoteMode(new ColumnQuoteMode(2)).build();

В качестве альтернативы, если вы хотите процитировать все, вы можете использовать AlwaysQuoteMode, или если вы хотите полностью индивидуальное решение, вы можете написать свое собственное QuoteMode.

person James Bassett    schedule 11.04.2014
comment
Хорошо, спасибо. И есть ли такое решение, чтобы парсер оставлял кавычки там, где они были, и печатал строки без кавычек, если их не было на входе? В смысле, например. ,, --> ,null, (or ,,), "Bob" --> "Bob", Bob --> Bob and "" --> "" Возможно ли это с помощью SuperCSV или OpenCSV? - person user3521479; 11.04.2014
comment
В ридерах есть метод getUntokenizedRow(), но это не совсем то, что вам нужно. Я сомневаюсь, что многие библиотеки перейдут из CSV в Java и снова в CSV с идентичным вводом/выводом (данные будут такими же, но содержащая их структура может отличаться). - person James Bassett; 12.04.2014

Вы создаете свои собственные предпочтения.

CsvPreference excelPreference = new CsvPreference.Builder('\'', ',', "\n").build();
CsvListReader parser = new CsvListReader(Files.newBufferedReader(pathToFile , StandardCharsets.UTF_8), excelPreference);

После этого он будет выводиться, как и ожидалось. В этом примере вы удалите одинарную кавычку, если она есть в вашем CSV-файле, и сохраните двойную кавычку нетронутой.

person sendon1982    schedule 11.04.2014

В указанном вами CsvPreference.EXCEL_PREFERENCE символом кавычки является ", как описано в javadoc. Символ кавычки — это символ, который вы используете для переноса специальных символов, которые должны отображаться буквально.

Таким образом, для этих предпочтений подходящим способом создания содержимого CSV будет

id, name, city, age
1,"""Bob""",London,12

В противном случае парсер CSV просто думает

"Bob"

означает, буквально,

Bob

так как между кавычками нет другого специального символа. Но кавычка — это специальный символ, поэтому, если он появляется между кавычками, он будет буквально считаться кавычкой.

В качестве альтернативы укажите другой объект CsvPreference с другим символом кавычек.

Принимайте это решение только после того, как будете уверены в том, что отправляет вам ваш производитель CSV.

person Sotirios Delimanolis    schedule 10.04.2014
comment
Хорошо, я знаю. Я имею в виду, как преобразовать файл CSV в набор списка, чтобы сохранить кавычки. Если вы предоставляете другой CsvPreference, например. новый CsvPreference.Builder('\'', ',', \n).build() чем, это не работает: id, text 1, это не работает, чувак - person user3521479; 11.04.2014
comment
@ user3521479 В javadoc показано, как это сделать. sendon1982 также предоставляет пример. - person Sotirios Delimanolis; 11.04.2014