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

我正在编写一个 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 文件中打开 office,当然也不能搞乱其他常规转义情况(例如常规双引号和元组中的常规逗号)。我知道正则表达式很强大,但是在如此复杂的情况下,我们如何实现这个目标呢?

195970 次浏览

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

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

使 Java 产生相同的输出。

顺便说一下,Excel 使用的格式是发布的..。

编辑1: Excel 是这么做的
编辑2: 请注意,如果您使用“ Excel”作为外壳,那么 php 的 fputcsv所做的事情与 excel 完全相同。

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

变成了这样:

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

这里有几个图书馆,下面是两个例子:


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""."""
    
  • Unescape from 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"."
    

* You can download it from here.


❐ OpenCSV

If you use OpenCSV, you will not need to worry about escape or unescape, only for write or read the content.

  • Writing file:

    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();
    
  • Reading file:

    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();
    

* You can download it from here.

感谢托尼和保罗的快速反馈,非常有帮助。我通过 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+"\"")中

你也可以看看 Python 编写与 Excel 兼容的 csv文件。

我相信 Excel 的默认设置是字面引号字符加倍——也就是说,字面引号 "写成 ""

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

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

重要提示

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

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

String stringWithQuates = "\""+ "your,comma,separated,string" + "\"";

这将保留 CSV 文件中的逗号

如果您正在使用 CSVWriter。请检查您没有这个选项

.withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)

当我删除它的逗号显示如预期,而不是把它当作新的列

在 openCSV 中,使用以下方法创建 csvWriter obj,

CSVWriter csvWriter = new CSVWriter(writer, CSVWriter.DEFAULT_SEPARATOR, CSVWriter.DEFAULT_ESCAPE_CHARACTER, CSVWriter.DEFAULT_LINE_END, CSVWriter.DEFAULT_QUOTE_CHARACTER);

在这方面,DEFAULT_QUOTE_CHARACTER非常重要。 它将完全工作,如果你想插入任何’,’或’“’在 csv 文件。