Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trim leading and trailing spaces in OpenCSV

Tags:

java

trim

opencsv

I am using OpenCSV's CSVReader to read some comma separated values from a file. I'm not sure how to trim leading and trailing spaces. Sure, I could do String.trim() but it would be cleaner not to. In the documentation there is no such option specified.

like image 447
user1377000 Avatar asked Mar 15 '13 17:03

user1377000


3 Answers

If you are working with bean mapping and OpenCSV, I personally prefer to extend the MappingStrategy as it handles the final value assignments to their related fields. Imagine your fields are tab separated. Then you might have hard time to extend the CSVReader. Also, less coding is required.

In the following example, I am using a ColumnPositionMappingStrategy but yours can be any other MappingStrategy as populateNewBean is in the parent abstract class.

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);
        }
    };
}

As you can see, each field/line is trimmed before bean is populated.

like image 153
Youness Avatar answered Sep 17 '22 07:09

Youness


Can you switch to SuperCSV? It has an option to ignore surrounding spaces on its CsvPreference.Builder. It's a far superior library, IMO. If that preference doesn't do what you want, you could always extend the Tokenizer class and override readColumns. Otherwise, it looks like OpenCSV isn't very granular and would require you to extend CSVReader and override readNext. This might work:

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;
    }
}
like image 30
ngreen Avatar answered Sep 17 '22 07:09

ngreen


Using ngreen's idea I came up with the following working solution:

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;
    }
}
like image 33
Vinícius M. Freitas Avatar answered Sep 19 '22 07:09

Vinícius M. Freitas