Java 使用相同的转义和引号字符分隔CSV

Java 使用相同的转义和引号字符分隔CSV,java,csv,apache-commons-csv,Java,Csv,Apache Commons Csv,我有一个简单的CSV文件,如下所示: SellerProductID;ProductTextLong 1000;"a ""good"" Product" 这是尝试使用Apache CSV读入它的方法: try(读卡器=新的StringReader(内容)){ CSVFormat format=CSVFormat.DEFAULT.withDelimiter(“;”).withHeader().withEscape(“”).withQuo

我有一个简单的CSV文件,如下所示:

SellerProductID;ProductTextLong
1000;"a ""good"" Product"
这是尝试使用Apache CSV读入它的方法:

try(读卡器=新的StringReader(内容)){
CSVFormat format=CSVFormat.DEFAULT.withDelimiter(“;”).withHeader().withEscape(“”).withQuote(“”);
CSVParser records=format.parse(读取器);
System.out.println(records.iterator().next());
}
这不起作用,因为:

Exception in thread "main" java.lang.IllegalStateException: IOException reading next record: java.io.IOException: (startline 2) EOF reached before encapsulated token finished
    at org.apache.commons.csv.CSVParser$CSVRecordIterator.getNextRecord(CSVParser.java:145)
    at org.apache.commons.csv.CSVParser$CSVRecordIterator.next(CSVParser.java:171)
    at org.apache.commons.csv.CSVParser$CSVRecordIterator.next(CSVParser.java:137)
Caused by: java.io.IOException: (startline 2) EOF reached before encapsulated token finished
    at org.apache.commons.csv.Lexer.parseEncapsulatedToken(Lexer.java:288)
    at org.apache.commons.csv.Lexer.nextToken(Lexer.java:158)
    at org.apache.commons.csv.CSVParser.nextRecord(CSVParser.java:674)
    at org.apache.commons.csv.CSVParser$CSVRecordIterator.getNextRecord(CSVParser.java:142)
    ... 3 more
其他CSV工具(例如Google Sheets)可以很好地加载CSV

如果我使用另一个引号或转义字符,它会起作用,但遗憾的是,客户的CSV已设置


如何配置Apache CSV以允许相同的转义和引号字符?或者是否有任何方法可以修改流以动态替换引号字符(文件非常庞大)?

我已经查看了您的问题,这可能会对您有所帮助。请尝试将其与
一起使用。withNullString(“”)

整个问题在于“不是”转义字符

发件人:

嵌入的双引号字符可以用一对连续的双引号表示,或者用转义字符(如反斜杠)作为双引号的前缀

所以在本例中,“”只是两个相邻的引号字符,而转义字符是一个不同的字符,用于转义引号、换行符或分隔符

这就解决了这个问题(请注意,
withEscape()
的调用方式不同,但示例数据没有显示转义字符的实际含义):

try(读卡器=新的StringReader(内容)){
CSVFormat format=CSVFormat.DEFAULT.withDelimiter(“;”).withHeader().withEscape(“/”).withQuote(“”);
CSVParser records=format.parse(读取器);
System.out.println(records.iterator().next());
}