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

Dre*_*mer 62 java regex csv oracle excel

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

不幸的是,数据内容可能非常棘手.仍然逗号是deliminator,但行上的一些数据可能是这样的:

ID FN LN 年龄 评论

123,约翰,史密斯,39岁,我说"嘿,我是5'10"."

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

我说"嘿,我5'10"."

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

Pau*_*gas 105

有几个图书馆.这是两个例子:


❐ApacheCommons Lang

阿帕奇共享郎包括一类特殊的逃避或UNESCAPE字符串(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""."""
    
    Run Code Online (Sandbox Code Playgroud)
  • 来自CSV的Unescape

    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"."
    
    Run Code Online (Sandbox Code Playgroud)

*您可以从 这里下载.


❐OpenCSV

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

  • 写文件:

    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();
    
    Run Code Online (Sandbox Code Playgroud)
  • 阅读文件:

    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();
    
    Run Code Online (Sandbox Code Playgroud)

*您可以从 这里下载.

  • 这是正确的答案.程序员不应该重新发明轮子(除非有一个很好的理由). (2认同)

Ton*_*nis 34

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

将这些内容放入Excel,将它们保存为CSV,然后使用文本编辑器检查文件.然后,您将了解Excel适用于这些情况的规则.

使Java生成相同的输出.

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

****编辑1:****以下是Excel的作用
****编辑2:****请注意,fputcsv如果使用"作为附件,php的功能与excel完全相同.

rdeslonde@mydomain.com
Richard
"This is what I think"
Run Code Online (Sandbox Code Playgroud)

变成了这个:

Email,Fname,Quoted  
rdeslonde@mydomain.com,Richard,"""This is what I think"""
Run Code Online (Sandbox Code Playgroud)

  • @MartijnCourteaux做这个"""""""""这就是我的想法,suckas!"""""""""":) (6认同)
  • 答案不好.Apache commons在没有MS Excel的情况下完成所有工作 (5认同)
  • 如何逃避`""""? (3认同)

Dre*_*mer 14

感谢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);
}
Run Code Online (Sandbox Code Playgroud)

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


Li-*_*Yip 5

您还可以查看Python 如何编写与 Excel 兼容的csv文件。

我相信 Excel 的默认设置是将文字引号字符加倍 - 也就是说,文字引号"写为"".