Обрезать начальные и конечные пробелы в OpenCSV

Я использую OpenCSV CSVReader для чтения некоторых значений, разделенных запятыми, из файла. Я не уверен, как обрезать начальные и конечные пробелы. Конечно, я мог бы сделать String.trim(), но было бы чище этого не делать. В документации такой параметр не указан.


person user1377000    schedule 15.03.2013    source источник
comment
Как не чище использовать String.trim()?   -  person syb0rg    schedule 15.03.2013
comment
Потому что мне нужно написать одну лишнюю строку. Кроме того, он должен создать совершенно новый объект, что немного менее эффективно.   -  person user1377000    schedule 15.03.2013
comment
Вы не можете выделить 1 дополнительную строку в исходном коде для функции, которую знаете, как использовать?   -  person syb0rg    schedule 15.03.2013
comment
Я согласен, что было бы неплохо, если бы объект CSVReader имел возможность для этого. В конструкторе есть опция «ignoreLeadingWhiteSpace», но я предполагаю, что она влияет только на пробелы вне кавычек?   -  person Leo Lansford    schedule 30.07.2013
comment
Я думаю, что библиотека CSV должна помещать содержимое в ячейки и читать содержимое ячеек точно, как оно есть. На этом его ответственность заканчивается. Разработчики несут ответственность за использование правильного контента для написания и преобразование прочитанного контента. Я уверен, что вы могли бы создать класс, обертывающий CSVReader, который бы обрезал () все поля, и тогда ваш код, выполняющий бизнес-логику, был бы чище.   -  person ppeterka    schedule 13.09.2013


Ответы (3)


Можно ли переключиться на SuperCSV? У него есть возможность игнорировать окружающие пространства на его CsvPreference.Builder. Это гораздо лучшая библиотека, ИМО. Если этот параметр не дает желаемого результата, вы всегда можете расширить класс Tokenizer и переопределить readColumns. В противном случае OpenCSV выглядит не очень детализированным и потребует от вас расширения CSVReader и переопределения readNext. Это может сработать:

class MyReader extends au.com.bytecode.opencsv.CSVReader {
    @Override public String[] readNext() throws IOException {
        String[] result = super.readNext();
        for (int i=0; i<result.length; i++) result[i] = result[i].trim();
        return result;
    }
}
person ngreen    schedule 20.03.2014
comment
Обратите внимание, что последний раз SuperCSV обновлялся в 2015 году. OpenCSV в настоящее время поддерживается. - person Andrew; 27.04.2020
comment
Это прискорбно. Я не следил за изменениями API OpenCSV, поэтому не знаю, насколько он улучшился. Конечно, java.time поддержка имеет большое значение. Тот факт, что OpenCSV готов внести критические изменения в основные выпуски, является хорошим знаком. - person ngreen; 28.04.2020

Если вы работаете с отображением bean-компонентов и OpenCSV, я лично предпочитаю расширить MappingStrategy, поскольку он обрабатывает окончательные назначения значений для соответствующих полей. Представьте, что ваши поля разделены вкладками. Тогда вам может быть трудно расширить CSVReader. Кроме того, требуется меньше кодирования.

В следующем примере я использую ColumnPositionMappingStrategy, но вы можете использовать любую другую MappingStrategy, поскольку populateNewBean находится в родительском абстрактном классе.

private <T> MappingStrategy<T> createMappingStrategy() {
    return new ColumnPositionMappingStrategy<T>() {
        @Override
        public T populateNewBean(String[] line) throws CsvDataTypeMismatchException, CsvConstraintViolationException,
                CsvRequiredFieldEmptyException, CsvValidationException {
            Arrays.setAll(line, (i) -> line[i].trim());
            return super.populateNewBean(line);
        }
    };
}

Как видите, каждое поле/строка обрезается перед заполнением бина.

person Youness    schedule 15.07.2020

Используя идею ngreen, я придумал следующее рабочее решение:

public class CSVReaderExtended extends CSVReader {

    private static final String EXP_ALPHA_AND_DIGITS = "[^a-zA-Z0-9]+";

    public CSVReaderExtended(Reader reader) {
        super(reader);
    }

    @Override
    public String[] readNext() throws IOException {
        String[] result = super.readNext();
        if (result == null)
            return null;

        for (int index = 0; index < result.length; index++) {
            result[index] = result[index].replaceAll(EXP_ALPHA_AND_DIGITS, "");
        }
        return result;
    }
}
person Vinícius M. Freitas    schedule 09.01.2018