Java commons-csv: QuoteMode.MINIMAL слишком много цитирует? - PullRequest
1 голос
/ 29 марта 2020

Я использую Java org.apache.commons.csv (версия 1.8) с режимом кавычек MINIMAL для записи файла CSV.

Мне интересно, ожидается ли следующее цитирование в отношении цитирования ячейки "foo bar ":

csvPrinter.printRecord("eggs", "foo bar   ", "spam");

дает на выходе:

eggs,"foo bar   ",spam

My ожидается, что двойные кавычки не должны присутствовать в режиме котировки MINIMAL .

Минимальный пример здесь:

import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintStream;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.csv.QuoteMode;

@Test
public void test() throws IOException {
    CSVFormat csvFormat = CSVFormat.EXCEL
            .withQuoteMode(QuoteMode.MINIMAL);

    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
    CSVPrinter csvPrinter = new CSVPrinter(writer, csvFormat);
    csvPrinter.printRecord("eggs", "foo bar   ", "spam");
    csvPrinter.flush();
    csvPrinter.close();
}

Для сравнения, та же запись, напечатанная с Python pandas, не содержит кавычек:

import pandas
import sys
import csv

df = pandas.DataFrame({'a': ['eggs'], 'b': ['foo bar  '], 'c': ['spam']})
df.to_csv(sys.stdout, quoting= csv.QUOTE_MINIMAL)

,a,b,c
0,eggs,foo bar  ,spam       <<< No quotes!

Я что-то упустил ...?

1 Ответ

1 голос
/ 29 марта 2020

Глядя на код CSVFormat , кавычки добавляются, когда ячейка заканчивается пробелом или любым символом с более низким значением цифры c, т. Е. Символ табуляции или новой строки

static final char SP = ' ';
...
case MINIMAL:
...
if (!quote) {
    pos = end - 1;
    c = value.charAt(pos);
    // Some other chars at the end caused the parser to fail, so for now
    // encapsulate if we end in anything less than ' '
    if (c <= SP) {
        quote = true;
    }
}

The:

// Некоторые другие символы в конце вызвали сбой синтаксического анализатора, поэтому пока
// инкапсулируем, если мы заканчиваем чем-то меньшим, чем ''

комментарий несколько криптоват c, поэтому я не знаю, есть ли ошибка в коде или в документации, где не сказано, что QuoteMode.MINIMAL делает это:

Кавычки в полях, которые содержат специальные символы, такие как разделитель полей, кавычки или любые символы в строке разделителя строк.

Что касается pandas, делающего что-то другое, это не так Что бы это ни значило, стандарта csv не существует, и цитирование ячейки, заканчивающейся пробелом, когда ваша цель заключать в кавычки как можно меньше, может быть правильным.

...