Comment échapper simultanément la virgule et les guillemets doubles pour un fichier CSV ?

J’écris une application Java pour exporter des données d’Oracle vers un fichier CSV.

Malheureusement, le contenu des données peut être assez délicat. La virgule reste le délimiteur, mais certaines données sur une ligne pourraient ressembler à ceci :

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

Voici donc l’une des chaînes dans la colonne comment :

I said “Hey, I am 5’10”."

Sans plaisanter, j’ai besoin d’afficher le commentaire ci-dessus sans compromis dans Excel ou Open Office à partir d’un fichier CSV généré par Java, et bien sûr sans perturber les autres cas d’échappement habituels (c’est-à-dire les guillemets doubles classiques et la virgule classique dans un tuple). Je sais que les expressions régulières sont puissantes, mais comment peut-on atteindre cet objectif dans une situation aussi compliquée ?


Source : Stack Overflow

Il existe plusieurs bibliothèques. Voici deux exemples :

❐ Apache Commons Lang

Apache Commons Lang inclut une classe spéciale pour échapper ou dé-échapper des chaînes (CSV, EcmaScript, HTML, Java, Json, XML) : org.apache.commons.lang3.StringEscapeUtils.

Échapper vers 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""."""

Dé-échapper depuis 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"."

  • Vous pouvez le télécharger depuis ici.

❐ OpenCSV

Si vous utilisez OpenCSV, vous n’aurez pas à vous soucier de l’échappement ou du dé-échappement, uniquement de l’écriture ou de la lecture du contenu.

Écriture de fichier :

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

Lecture de fichier :

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

  • Vous pouvez le télécharger depuis ici.