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

Posted

技术标签:

【中文标题】使用相同的转义和引号字符分隔 CSV【英文标题】:Using Same Escape and Quote Character Breaks CSV 【发布时间】:2021-01-13 11:32:36 【问题描述】:

我有一个像这样的简单 CSV 文件:

SellerProductID;ProductTextLong
1000;"a ""good"" Product"

这是使用 Apache CSV 读取它的尝试:

    try (Reader reader = new StringReader(content)) 
      CSVFormat format = CSVFormat.DEFAULT.withDelimiter(';').withHeader().withEscape('"').withQuote('"');
      CSVParser records = format.parse(reader);
      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 表格)可以很好地加载 CSV。

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

如何配置 Apache CSV 以允许使用相同的转义字符和引号字符?或者有什么方法可以修改流以动态替换引号字符(文件很大)?

【问题讨论】:

【参考方案1】:

整个问题是 " 不是"转义字符"。

来自Wikipedia:

然后,嵌入的双引号字符可以由一对连续的双引号表示,或者通过在双引号前加上转义字符(如反斜杠)来表示。

所以在这种情况下,“”只是两个相邻的引号字符,而转义字符是用于转义引号或换行符或分隔符的不同字符。

这修复了它(注意 withEscape() 的调用方式不同,但示例数据并未显示转义字符的实际含义):

try (Reader reader = new StringReader(content)) 
    CSVFormat format = CSVFormat.DEFAULT.withDelimiter(';').withHeader().withEscape('/').withQuote('"');
    CSVParser records = format.parse(reader);
    System.out.println(records.iterator().next());

【讨论】:

【参考方案2】:

我已经查看了您的问题,这个article 和这个post 可能会对您有所帮助。尝试同时使用.withNullString("")

【讨论】:

以上是关于使用相同的转义和引号字符分隔 CSV的主要内容,如果未能解决你的问题,请参考以下文章

将字符串写入 CSV 时转义逗号

如何为 CSV 文件同时转义逗号和双引号?

在引用的 csv 中匹配未转义的引号

正则表达式拆分字符串,不包括可转义引号之间的分隔符

Bigquery - 在 CSV(联合表)中处理双引号和管道字段分隔符

oracle转义符