Apache Commons CSV在Kotlin项目中输出额外双引号的原因、是否为预期行为及解决方法问询
嘿,我来帮你捋捋这个问题——你遇到的所谓“额外双引号”其实是符合CSV规范的预期行为,不是库的bug,咱们一步步说清楚:
为什么会出现“额外”的双引号?
你得先搞懂Apache Commons CSV遵循的CSV转义规则(RFC 4180规范):
当字段里包含双引号、逗号或者换行符时,库会做两件事:
- 把字段内部的每一个
"替换成两个""(这是CSV标准的转义方式,用来区分字段内部的引号和包裹字段的引号); - 因为这个字段包含了需要转义的特殊字符,所以会用一对双引号把整个转义后的字段包裹起来(这是你设置的
QuoteMode.MINIMAL的要求:只有必要时才给字段加引号)。
拿你的测试用例举例:
你的输入字段值是"foo014"(就是字符串本身带双引号),库处理它的流程是:
- 第一步:转义内部双引号 → 变成
""foo014""; - 第二步:因为字段里有转义前的双引号,所以给整个转义后的字符串套上外层双引号 → 最终变成
"""foo014"""。
你觉得这多了一个双引号,但其实这是规范要求的——这样生成的CSV被解析时,才能正确还原出你原始的"foo014"字段值:解析器会先去掉外层的引号,再把""还原成单个",完美回到你最初的输入。
而你测试用例里写的expected值""foo014""是不符合CSV规范的:如果CSV字段写成这样,解析器会把它当成普通字符串(没有外层引号包裹),解析后得到的是""foo014""(也就是两个双引号加foo014加两个双引号),这和你原始的输入完全不一致,所以你的测试预期本身是错的。
这是预期行为吗?
绝对是预期行为!Apache Commons CSV的处理完全符合国际标准的CSV规范,这么做是为了确保生成的CSV文件能被所有兼容的解析工具(比如Excel、Google Sheets、其他CSV库)正确解析,不会出现数据错乱。
怎么解决?(不想禁用引号的话)
最合理的解决方式是修正你的测试用例的预期值,把""foo014""改成"""foo014""",这样测试就能通过,而且生成的CSV是标准可解析的。
如果你确实有特殊业务需求,必须输出不符合规范的格式(非常不建议这么做,会导致解析问题),那可以考虑:
- 预处理字段值:在传入CSV生成函数前,手动把字段里的
"替换成你想要的形式(比如直接去掉,或者替换成单个"而不转义),但这样会破坏数据的准确性; - 自定义QuoteMode:不过Apache Commons CSV没有提供这种非标准的QuoteMode,你得自己实现,但这会让生成的CSV无法被标准工具正确解析,风险很高。
另外,你也可以检查一下原始数据:如果这些双引号是输入时的误操作(比如数据本身不应该带双引号),那在生成CSV前去掉这些多余的双引号,就能从根源上避免这个问题。
内容来源于stack exchange

