
Le format de fichier CSV ("Comma Separated Values") sert à échanger des données entre différentes applications et à sauvegarder des données. Les avantages de ce format de données sont d'utiliser une faible bande passante et peu d'espace de stockage.
Autrement dit:
On peut utiliser
colonne A,colonne B,colonne C "Il a dit ""coucou !"" hier.","Hé, Je contiens une virgule !",125
La fonction javascript suivante retourne un tableau contenant les les différents champs d'une ligne CSV correspondant à une fiche. On assume que la ligne ne contient pas de \r
String.prototype.splitCSV = function(sep , trim) {
sep = sep || ",";
if (!trim && this.indexOf('"') < 0) return this.split(sep);
var elts = this.split(sep), elt = '', out = [], nq, i, j;
for (i = 0; i < elts.length ; i++) {
if (elt =='') elt = elts[i]; else elt += sep + elts[i];
nq = elt.length - elt.replace(/"/g , '').length;
if (nq % 2 == 0) {
if (nq > 0) {
elt = elt.replace(/^\s+|\s+$/g,""); //Supprime les espaces encadrant les " qui limitent les éléments de la chaîne
j = elt.indexOf('"');
elt = elt.substring(0,j) + elt.substring(j+1);
j = elt.lastIndexOf('"');
elt = elt.substring(0,j) + elt.substring(j+1);
elt = elt.replace(/""/g , '"')
}
if (trim) out.push(elt.replace(/^\s+|\s+$/g,"")); else out.push(elt);
elt = '';
}
}
if (elt == '') return out; else return false; //La chaine contient un \n, à combiner avec la chaine suivante
}
La même fonction en php, toujours en assumant que la ligne ne contient pas de \r
function splitCSV($string, $sep="," , $trim = false) {
if (!$trim && strpos($string , '"') === false) return explode($sep, $string);
$elts = explode($sep, $string);
$elt = '';
$out = array();
for ($i = 0; $i < count($elts); $i++) {
if ($elt == '') $elt = $elts[$i]; else $elt .= $sep . $elts[$i];
$nq = substr_count($elt, '"');
if ($nq %2 == 0) {
if ($nq > 0) {
$elt = trim($elt); //Supprime les espaces encadrant les " qui limitent les éléments de la chaîne
$elt = substr_replace($elt, '', strpos($elt, '"'), 1);
$elt = substr_replace($elt, '', strrpos($elt, '"'), 1);
$elt = str_replace('""', '"', $elt);
}
if ($trim) $out[] = trim($elt); else $out[] = $elt;
$elt = '';
}
}
if ($elt == '') return $out; else return false; //La chaine contient un \n, à combiner avec la chaine suivante
}
La fonction javascript suivante retourne un tableau contenant les les différents champs d'une chaîne CSV d'un ensemble de fiches, avec ou sans \r.
String.prototype.parseCSV = function(sep , trim) {
sep = sep || ",";
var ch = '', out = [] , ax , ay , i;
ay = this.replace(/[\r\n]*$/ , '').replace(/\r/g , '').split("\n");
for (i = 0; i < ay.length ; i++) {
if (ch == '') ch = ay[i]; else ch += "\n" + ay[i];
ax = ch.splitCSV(sep, trim);
if (ax !== false) {
out.push(ax);
ch = '';
}
}
if (ch == '') return out; else return false; //La chaîne est mal formée
}
La même fonction en php
function parseCSV($string , $sep="," , $trim = false) {
$string = preg_replace('/[\r\n]*$/' , '' , $string);
$ay = explode("\n" , str_replace("\r" , '' , $string)); //$ay = preg_split('/\r?\n/' , $string);
$ch = '';
$out = array();
foreach($ay as $ligne) {
if ($ch == '') $ch = $ligne; else $ch .= "\n$ligne";
$ax = splitCSV($ch , $sep, $trim);
if ($ax !== false) {
$out[] = $ax;
$ch = '';
}
}
if ($ch == '') return $out; else return false; //La chaîne est mal formée
}
Array.prototype.joinCSV = function(sep) {
var i, s , sep = sep || ',' ,val = this;
for( i = 0 ; i < val.length ; i++) {
if (typeof(val[i]) != 'string') val[i] = val[i].toString();
s = val[i].replace(/"/g , '""');
if (val[i] !== s || s.indexOf(sep) >= 0 || s.indexOf('\n') >= 0) val[i] = '"' + s + '"';
}
return val.join(sep);
};
function joinCSV($a , $sep = ',') {
$count = 0;
foreach($a as $key => $val) {
$val = str_replace('"' , '""' , $val , $count);
if ($count > 0 || strpos($val , $sep) !== false || strpos($val , "\n") !== false) $a[$key] = '"' . $val . '"';
}
return implode($sep , $a);
}
Array.prototype.makeCSV = function(sep) {
var i, sep = sep || ',' , a = [] , val = this;
for (var i = 0 ; i < val.length ; i++) {
a.push(val[i].joinCSV(sep));
}
return val.join('\n');
}
function makeCSV($a2 , $sep = ',') {
$a = array();
foreach($a2 as $row) {
$a[] = joinCSV($row , $sep);
}
return implode("\n" , $a);
}
Dans ce wiki comme dans les autres wikis utilisant le caractère d'échappement \ pour échapper un caractère qui doit être interprété comme caractère normal et pas comme caractère de la syntaxe wiki, on indique la présence d'une virgule dans un champ en la précédant de \
Ce format CSV est cohérent par rapport à la syntaxe wiki, mais il n'est pas traité correctement par les autres applications et il n'accepte pas de séparateur de ligne dans un champ. On peut traiter ses lignes à l'aide des 2 fonctions php suivantes:
function splitCSVe($row , $tr = false) {
$cells = preg_split('/(?<!\\\),/',$row);
if ($tr) array_walk($cells,create_function('&$v','$v = str_replace("\,",",",trim($v));'));
return $cells;
}
function joinCSVe($a) {
array_walk($a,create_function('&$v','$v = str_replace("," , "\\\," , $v);'));
return implode(',' , $a);
}