我正在使用OpenCSV的CSVReader
来读取文件中的一些逗号分隔值。我不确定如何修剪前导和尾随空格。当然,我可以做String.trim()
,但不要那么干净。在documentation中没有指定此类选项。
答案 0 :(得分:4)
您可以切换到SuperCSV
吗?它可以选择忽略CsvPreference.Builder
上的周围空格。这是一个非常优越的图书馆,IMO。如果该首选项不能满足您的要求,您可以随时扩展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;
}
}
答案 1 :(得分:1)
使用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;
}
}
答案 2 :(得分:1)
如果您正在使用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);
}
};
}
如您所见,在填充bean之前,将修剪每个字段/行。