Utiliser recode en PHP pour essayer de deviner l'encodage d'un fichier
Par Clochix le vendredi 22 septembre 2006, 00:17 - Technoweb - Lien permanent
On tombe parfois sur des fichiers à l'encodage étrange et bizzare. En cherchant comment découvrir cet encodage histoire de lire correctement le fichier, je suis tombé sur la commande GNU recode qui permet de traduire des fichiers entre plus de 150 charsets. Elle offre de très nombreuses options, et dispose même d'un manuel en français (si le serveur est en rade, essayez dans les archives du réseau).
La commande peut aussi être utilisée depuis PHP (sous GNU/Linux uniquement) via une extension, facile à installer (apt-get install php5-recode), mais qui peut poser certains problèmes de compatibilité avec d'autres.
Pour déterminer le jeu de caractères d'un fichier, j'ai écrit un petit script à lancer en ligne de commande qui extrait d'un fichier toutes les chaînes contenant des charactères de code ASCII supérieur à 127 et les traduit dans divers encodages.
#!/usr/bin/php
<?php
// Extract all words containing ASCII code > 127 and try to recode them from as many charset as possible.
// syntax : php charsets_try file1 file2 ...
include ("charsets_ref.php");
$dst = "UTF8"; // charset to convert to
$tConv = Array (); // for the string to convert
array_shift($argv); // the first item is the command name
foreach ($argv as $file)
{
$nbl = 0;
$tFile = file($file);
foreach ($tFile as $v)
{
// look for word containing ASCII code > 127
if (preg_match_all('/\b.{0,20}\x80-\xFF+.{0,20}\b/', $v, $m) > 0)
{
$nbl++;
foreach ($m0 as $string)
{
$tConv$string = '';
}
}
}
// recode each word
foreach ($tConv as $string => $v)
{
echo "---
";
echo $string . "
";
foreach ($tCharsets as $src)
{
try{
echo " $src : " . @recode_string("$src..$dst", $string) . "
";
} catch(Exception $e) {
echo "Erreur : " . $e->getMessage() . "
";
}
}
}
echo "===
The file $file contains " . count($tConv) . " string to recode in $nbl lines
";
}
?>
J'ai mis la liste des charsets disponibles dans un fichier séparé pour ne pas alourdir. Celui-ci contient quelque chose comme
<?php
$tCharsets = Array('037',
'038',
'1004',
(...)
'yu');
?>
Recode n'est pas le seul moyen de gérer les conversions d'encodage en PHP, on peut aussi faire appel à iconv ou mbstring. Je n'ai pas vraiment trouvé de comparaison entre ces 3 bibliothèques, tout commentaire sera le bienvenu.
en cherchant un peu plus loin, je suis tombé sur ce billet expliquant comment convertir les caractères spéciaux en brave ASCII: Conversion complète de chaînes de caractères vers l'ASCII en php