【问题标题】:How to escape comma and double quote at same time for CSV file?如何为 CSV 文件同时转义逗号和双引号?
【发布时间】:2012-05-14 04:13:22
【问题描述】:

我正在编写一个 Java 应用程序来将数据从 Oracle 导出到 csv 文件

不幸的是,数据的内容可能相当棘手。仍然逗号是分隔符,但是一行上的一些数据可能是这样的:

| ID    |   FN    |   LN   |  AGE   |  COMMENT                   |
|----------------------------------------------------------------|
| 123   |  John   |  Smith |   39   | I said "Hey, I am 5'10"."  |
|----------------------------------------------------------------|

所以这是comment 列上的字符串之一:

我说“嘿,我是 5'10”。”

不开玩笑,我需要在 Excel 中显示以上评论,或者从 Java 生成的 CSV 文件中打开办公室,当然不能搞乱其他常规转义情况(即常规双引号和元组中的常规逗号) .我知道正则表达式很强大,但是在如此复杂的情况下我们如何才能达到目标呢?

【问题讨论】:

  • 我很确定 Oracle(以及其他主要的 RDBMS)具有执行此功能的“导出”功能。除此之外,考虑到需要这种类型的功能的普遍性,可能会有一个开源版本可以通过 JDBC 与几乎任何东西进行交互。
  • 感谢 X-Zero 但这里的工作实际上依赖于控制器端。但仍然非常有用的想法:)
  • 对于 Swift,github.com/Daniel1of1/CSwiftV 是 rfc4180

标签: java regex excel oracle csv


【解决方案1】:

Excel 必须能够处理完全相同的情况。

将这些内容放入 Excel,将它们保存为 CSV,然后使用文本编辑器检查文件。然后你就会知道 Excel 适用于这些情况的规则。

让 Java 产生相同的输出。

顺便说一下,Excel 使用的格式已经发布...

**** 编辑 1:**** 这是 Excel 所做的
****编辑 2:**** 请注意,如果您使用 " 作为附件,则 php 的 fputcsv 与 excel 执行相同的操作。

rdeslonde@mydomain.com
Richard
"This is what I think"

变成这样:

Email,Fname,Quoted  
rdeslonde@mydomain.com,Richard,"""This is what I think"""

【讨论】:

  • 托尼这是个好主意。我应该这样想,那么这应该是一件容易的事。
  • 如何逃脱""""
  • @MartijnCourteaux 通过这样做 """"""""" 这就是我的想法,糟透了!""""""""" :)
  • 错误答案。 Apache commons 可以在没有 MS Excel 的情况下完成所有工作。
【解决方案2】:

有几个库。这里有两个例子:


❐ Apache Commons Lang

Apache Commons Lang 包含一个特殊的类来转义或取消转义字符串(CSV、EcmaScript、HTML、Java、Json、XML):org.apache.commons.lang3.StringEscapeUtils

  • 转义到 CSV

    String escaped = StringEscapeUtils
        .escapeCsv("I said \"Hey, I am 5'10\".\""); // I said "Hey, I am 5'10"."
    
    System.out.println(escaped); // "I said ""Hey, I am 5'10""."""
    
  • 转义来自 CSV

    String unescaped = StringEscapeUtils
        .unescapeCsv("\"I said \"\"Hey, I am 5'10\"\".\"\"\""); // "I said ""Hey, I am 5'10""."""
    
    System.out.println(unescaped); // I said "Hey, I am 5'10"."
    

* 你可以从here下载。


❐ OpenCSV

如果您使用OpenCSV,则无需担心转义或取消转义,仅用于写入或读取内容。

  • 编写文件:

    FileOutputStream fos = new FileOutputStream("awesomefile.csv"); 
    OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
    CSVWriter writer = new CSVWriter(osw);
    ...
    String[] row = {
        "123", 
        "John", 
        "Smith", 
        "39", 
        "I said \"Hey, I am 5'10\".\""
    };
    writer.writeNext(row);
    ...
    writer.close();
    osw.close();
    os.close();
    
  • 读取文件:

    FileInputStream fis = new FileInputStream("awesomefile.csv"); 
    InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
    CSVReader reader = new CSVReader(isr);
    
    for (String[] row; (row = reader.readNext()) != null;) {
        System.out.println(Arrays.toString(row));
    }
    
    reader.close();
    isr.close();
    fis.close();
    

* 你可以从here下载。

【讨论】:

  • 感谢保罗的建议。使用 rgx 是一个好主意并且非常灵活,但我们可以在不使用额外库的情况下实现这一点吗?
  • 再一次,如果在下一个项目中,我可以有特权在 Maven 中添加更多依赖项,那么这是一个非常支持的想法和有用的信息。 :D
  • commons lang 因为这个问题很糟糕:issues.apache.org/jira/browse/LANG-857;它甚至更糟糕,因为人们修补了这个问题,但没有发布日期
  • 已修复自 Apache Commons Lang 3.2 起
  • 这是正确答案。程序员不应该重新发明轮子(除非有很好的理由)。
【解决方案3】:

感谢 Tony 和 Paul 的快速反馈,这非常有帮助。我实际上通过 POJO 找到了解决方案。这里是:

if (cell_value.indexOf("\"") != -1 || cell_value.indexOf(",") != -1) {
    cell_value = cell_value.replaceAll("\"", "\"\"");
    row.append("\"");
    row.append(cell_value);
    row.append("\"");
} else {
    row.append(cell_value);
}

简而言之,如果单元格内的字符串中有逗号或双引号等特殊字符,则首先通过添加额外的双引号(如"\"\"")来转义双引号("\""),然后将整个事情变成双引号(如"\""+theWholeThing+"\""

【讨论】:

    【解决方案4】:

    你也可以看看Python writes Excel-compatible csv files.

    我相信 Excel 的默认设置是为文字引号字符加倍 - 即文字引号 " 写为 ""

    【讨论】:

    • 谢谢丽昂。在发布我自己的答案之前,我没有收到您的帖子。 Python 确实获得了更多用于 CVS 生成的库方法。
    • 原始问题没有提到 Python。
    • @JamesWatkins:OP 没有提到 Python——尽管如此,Python 文档中有有用的信息。
    【解决方案5】:
    "cell one","cell "" two","cell "" ,three"
    

    将此保存到 csv 文件并查看结果,因此使用双引号对其进行转义

    重要提示

    "cell one","cell "" two", "cell "" ,three"
    

    会给你一个不同的结果,因为逗号后面有一个空格,这将被视为“

    【讨论】:

      【解决方案6】:
      String stringWithQuates = "\""+ "your,comma,separated,string" + "\"";
      

      这将在 CSV 文件中保留逗号

      【讨论】:

      • 请注意,问题已经被回答,并且答案已经被接受。您提出的解决方案不会转义逗号。
      【解决方案7】:

      如果您使用的是 CSVWriter。检查您是否没有该选项

      .withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)
      

      当我删除它时,逗号按预期显示,而不是将其视为新列

      【讨论】:

      • CSVWriter csvWriter = new CSVWriter(writer, CSVWriter.DEFAULT_SEPARATOR, CSVWriter.DEFAULT_ESCAPE_CHARACTER, CSVWriter.DEFAULT_LINE_END, CSVWriter.NO_QUOTE_CHARACTER);如果像这样创建 csvwrite,逗号将无法正确处理。
      • @silver_fox 非常感谢。它节省了我的时间
      猜你喜欢
      • 2017-09-28
      • 1970-01-01
      • 1970-01-01
      • 2018-07-27
      • 1970-01-01
      • 1970-01-01
      • 2019-05-02
      • 1970-01-01
      • 2019-03-28
      相关资源
      最近更新 更多