J'ai un petit soucis avec les caract=E8res fran=E7ais d'un fichier :
Un petit 'file' Unixien du fichier :-) : Fichier1.csv: ISO-8859 C++
program text, with very long lines, with CRLF line terminators (Nota:
ce n'est cependant pas un programme C++).
Je voudrais substituer tous les caract=E8res accentu=E9s par leurs
=E9quivalents sans accent (tr/=E9=E8=EA/eee/ par exemple). Ces caract=E8res
ne semblent pas du tout =EAtre reconnue par perl, dans mes regex.
Je voudrais substituer tous les caractères accentués par leurs équivalents sans accent (tr/éèê/eee/ par exemple). Ces caractères ne semblent pas du tout être reconnue par perl, dans mes regex.
Sauriez-vous comment faire cette manipulation ?
La toute première chose à faire, c'est de faire en sorte que la chaîne à traitée soit considérée par Perl comme une chaîne de caractères Unicode. Pour ça, il faut absolument une version 5.8 de Perl, et selon les cas :
- utiliser « Encode::decode $encoding, $string » si la chaîne est déjà en mémoire ;
- utiliser « binmode $filehandle, ":encoding($encoding)" » avant de lire la chaîne depuis $filehandle.
Une fois que la chaîne est bien reconnue par Perl comme de l'Unicode, la méthode que j'apprécie personnellement pour désaccentuer est de mettre la chaîne sous forme normale KD (ce qui peut se faire avec Unicode::Normalize::NFKD), et de supprimer les caractères combinants (ce qui peut se faire avec « s/pM//g »), voire éventuellement tous les caractères non-ASCII (« s/[^x00-x7F]//g », la différence étant le résultat sur, par exemple, un epsilon avec un esprit).
"ctobini" wrote in message
<1138126300.494972.137220@g43g2000cwa.googlegroups.com>:
Je voudrais substituer tous les caractères accentués par leurs
équivalents sans accent (tr/éèê/eee/ par exemple). Ces caractères
ne semblent pas du tout être reconnue par perl, dans mes regex.
Sauriez-vous comment faire cette manipulation ?
La toute première chose à faire, c'est de faire en sorte que la chaîne à
traitée soit considérée par Perl comme une chaîne de caractères Unicode.
Pour ça, il faut absolument une version 5.8 de Perl, et selon les cas :
- utiliser « Encode::decode $encoding, $string » si la chaîne est déjà en
mémoire ;
- utiliser « binmode $filehandle, ":encoding($encoding)" » avant de lire la
chaîne depuis $filehandle.
Une fois que la chaîne est bien reconnue par Perl comme de l'Unicode, la
méthode que j'apprécie personnellement pour désaccentuer est de mettre la
chaîne sous forme normale KD (ce qui peut se faire avec
Unicode::Normalize::NFKD), et de supprimer les caractères combinants (ce qui
peut se faire avec « s/pM//g »), voire éventuellement tous les caractères
non-ASCII (« s/[^x00-x7F]//g », la différence étant le résultat sur, par
exemple, un epsilon avec un esprit).
Je voudrais substituer tous les caractères accentués par leurs équivalents sans accent (tr/éèê/eee/ par exemple). Ces caractères ne semblent pas du tout être reconnue par perl, dans mes regex.
Sauriez-vous comment faire cette manipulation ?
La toute première chose à faire, c'est de faire en sorte que la chaîne à traitée soit considérée par Perl comme une chaîne de caractères Unicode. Pour ça, il faut absolument une version 5.8 de Perl, et selon les cas :
- utiliser « Encode::decode $encoding, $string » si la chaîne est déjà en mémoire ;
- utiliser « binmode $filehandle, ":encoding($encoding)" » avant de lire la chaîne depuis $filehandle.
Une fois que la chaîne est bien reconnue par Perl comme de l'Unicode, la méthode que j'apprécie personnellement pour désaccentuer est de mettre la chaîne sous forme normale KD (ce qui peut se faire avec Unicode::Normalize::NFKD), et de supprimer les caractères combinants (ce qui peut se faire avec « s/pM//g »), voire éventuellement tous les caractères non-ASCII (« s/[^x00-x7F]//g », la différence étant le résultat sur, par exemple, un epsilon avec un esprit).
Antoun
(...)
Je voudrais substituer tous les caractères accentués par leurs équivalents sans accent (tr/éèê/eee/ par exemple). Ces caractères ne semblent pas du tout être reconnue par perl, dans mes regex.
pour que les caractères accentués soient reconnus par les regex, sans qu'il y ait besoin de substitution, il suffit d'utiliser une locale, par ex. :
Je voudrais substituer tous les caractères accentués par leurs
équivalents sans accent (tr/éèê/eee/ par exemple). Ces caractères
ne semblent pas du tout être reconnue par perl, dans mes regex.
pour que les caractères accentués soient reconnus par les regex, sans
qu'il y ait besoin de substitution, il suffit d'utiliser une locale, par
ex. :
Je voudrais substituer tous les caractères accentués par leurs équivalents sans accent (tr/éèê/eee/ par exemple). Ces caractères ne semblent pas du tout être reconnue par perl, dans mes regex.
pour que les caractères accentués soient reconnus par les regex, sans qu'il y ait besoin de substitution, il suffit d'utiliser une locale, par ex. :
pour que les caractères accentués soient reconnus par les regex, sans qu'il y ait besoin de substitution, il suffit d'utiliser une locale, par
Ce n'est vraiment pas une bonne idée, les API localisées sont mal définies et globalement peu fiables. Mieux vaut largement utiliser l'excellent support Unicode de Perl >= 5.8.
Antoun wrote in message <43d6b628$0$16233$626a54ce@news.free.fr>:
pour que les caractères accentués soient reconnus par les regex, sans
qu'il y ait besoin de substitution, il suffit d'utiliser une locale, par
Ce n'est vraiment pas une bonne idée, les API localisées sont mal définies
et globalement peu fiables. Mieux vaut largement utiliser l'excellent
support Unicode de Perl >= 5.8.
pour que les caractères accentués soient reconnus par les regex, sans qu'il y ait besoin de substitution, il suffit d'utiliser une locale, par
Ce n'est vraiment pas une bonne idée, les API localisées sont mal définies et globalement peu fiables. Mieux vaut largement utiliser l'excellent support Unicode de Perl >= 5.8.
ctobini
Bonjour à tous et merci pour vos réponses,
J'ai utilisé avec succès : use Encode; use Unicode::Normalize;
avec :
open FILEHANDLE, $file; binmode FILEHANDLE, ":encoding(iso-8859-1"); while (<FILEHANDLE>) { $_ = NFKD($_); s/pM//g; }
J'aurais 2 petites questions sur cette méthode :
- Y a t-il moyen de vérifier et adapter le binmode() en fonction du codage en entrée ? - a quoi correspond la méthode de normalisation KD du module Unicode ?
Merci.
C. Tobini
Bonjour à tous et merci pour vos réponses,
J'ai utilisé avec succès :
use Encode;
use Unicode::Normalize;
avec :
open FILEHANDLE, $file;
binmode FILEHANDLE, ":encoding(iso-8859-1");
while (<FILEHANDLE>) {
$_ = NFKD($_);
s/pM//g;
}
J'aurais 2 petites questions sur cette méthode :
- Y a t-il moyen de vérifier et adapter le binmode() en fonction du
codage en entrée ?
- a quoi correspond la méthode de normalisation KD du module Unicode ?
J'ai utilisé avec succès : use Encode; use Unicode::Normalize;
avec :
open FILEHANDLE, $file; binmode FILEHANDLE, ":encoding(iso-8859-1"); while (<FILEHANDLE>) { $_ = NFKD($_); s/pM//g; }
J'aurais 2 petites questions sur cette méthode :
- Y a t-il moyen de vérifier et adapter le binmode() en fonction du codage en entrée ? - a quoi correspond la méthode de normalisation KD du module Unicode ?
Merci.
C. Tobini
Paul Gaborit
À (at) 26 Jan 2006 05:02:46 -0800, "ctobini" écrivait (wrote):
- Y a t-il moyen de vérifier et adapter le binmode() en fonction du codage en entrée ?
Réponse de normand : oui et non.
Un script perl peut dynamiquement choisir un mode d'encodage parmi plusieurs modes à appliquer à un flux (en entrée ou en sortie). Je crois même qu'il doit être possible de changer l'encodage en cours d'écriture (je n'ai jamais essayé...).
La question reste "sur quels critères choisir l'encodage à appliquer?" Et là, je ne connais rien d'automatique. Certains codages étant indiscernables les uns des autres, il faut donc une information externe...
-- Paul Gaborit - <http://perso.enstimac.fr/~gaborit/> Perl en français - <http://perl.enstimac.fr/>
À (at) 26 Jan 2006 05:02:46 -0800,
"ctobini" <ctemp2@free.fr> écrivait (wrote):
- Y a t-il moyen de vérifier et adapter le binmode() en fonction du
codage en entrée ?
Réponse de normand : oui et non.
Un script perl peut dynamiquement choisir un mode d'encodage parmi
plusieurs modes à appliquer à un flux (en entrée ou en sortie). Je
crois même qu'il doit être possible de changer l'encodage en cours
d'écriture (je n'ai jamais essayé...).
La question reste "sur quels critères choisir l'encodage à appliquer?"
Et là, je ne connais rien d'automatique. Certains codages étant
indiscernables les uns des autres, il faut donc une information
externe...
--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>
À (at) 26 Jan 2006 05:02:46 -0800, "ctobini" écrivait (wrote):
- Y a t-il moyen de vérifier et adapter le binmode() en fonction du codage en entrée ?
Réponse de normand : oui et non.
Un script perl peut dynamiquement choisir un mode d'encodage parmi plusieurs modes à appliquer à un flux (en entrée ou en sortie). Je crois même qu'il doit être possible de changer l'encodage en cours d'écriture (je n'ai jamais essayé...).
La question reste "sur quels critères choisir l'encodage à appliquer?" Et là, je ne connais rien d'automatique. Certains codages étant indiscernables les uns des autres, il faut donc une information externe...
-- Paul Gaborit - <http://perso.enstimac.fr/~gaborit/> Perl en français - <http://perl.enstimac.fr/>
Nicolas George
"ctobini" wrote in message :
open FILEHANDLE, $file; binmode FILEHANDLE, ":encoding(iso-8859-1");
Deux petites remarques ici :
- Si c'est un fichier qu'on ouvre (par opposition à un fichier déjà ouvert, ou une socket, ou...), on peut faire le binmode à l'ouverture, avec la forme à trois arguments (qui est de toutes façons préférable) :
open FILEHANDLE, "<:encoding(iso-8859-1)", $file;
- Puisque c'est du Perl récent, on peut utiliser l'autovivification des scalaires pour les filehandles :
open my $filehandle, ...;
et utiliser $filehandle partout à la place de FILEHANDLE. Cette manière d'écrire présente de nombreux avantages.
- Y a t-il moyen de vérifier et adapter le binmode() en fonction du codage en entrée ?
Tu veux dire : essayer de détecter automatiquement l'encodage parmi quelques uns plausibles ? C'est techniquement plus ou moins possible, mais ça présente pas mal de complications, et en particulier le fait de lire un bout du fichier avant de faire le binmode, et donc de réinjecter le texte dans le fichier si on veut un vrai fichier. Il y a un module Encoding::Detect sur le CPAN, mais je ne sais pas s'il marche bien.
- a quoi correspond la méthode de normalisation KD du module Unicode ?
Ça convertit le texte sous forme normalisée KD définie par le Standard Unicode <URL: http://www.unicode.org/reports/tr15/ >. En très gros, ça décompose au maximum les caractères sous forme de radical + caractères combinants (ce qui permet justement d'enlever les caractères. La figure 3 de l'URL que j'ai donnée me semble assez parlante.
"ctobini" wrote in message
<1138280566.127540.148870@f14g2000cwb.googlegroups.com>:
open FILEHANDLE, $file;
binmode FILEHANDLE, ":encoding(iso-8859-1");
Deux petites remarques ici :
- Si c'est un fichier qu'on ouvre (par opposition à un fichier déjà ouvert,
ou une socket, ou...), on peut faire le binmode à l'ouverture, avec la
forme à trois arguments (qui est de toutes façons préférable) :
open FILEHANDLE, "<:encoding(iso-8859-1)", $file;
- Puisque c'est du Perl récent, on peut utiliser l'autovivification des
scalaires pour les filehandles :
open my $filehandle, ...;
et utiliser $filehandle partout à la place de FILEHANDLE. Cette manière
d'écrire présente de nombreux avantages.
- Y a t-il moyen de vérifier et adapter le binmode() en fonction du
codage en entrée ?
Tu veux dire : essayer de détecter automatiquement l'encodage parmi quelques
uns plausibles ? C'est techniquement plus ou moins possible, mais ça
présente pas mal de complications, et en particulier le fait de lire un bout
du fichier avant de faire le binmode, et donc de réinjecter le texte dans le
fichier si on veut un vrai fichier. Il y a un module Encoding::Detect sur le
CPAN, mais je ne sais pas s'il marche bien.
- a quoi correspond la méthode de normalisation KD du module Unicode ?
Ça convertit le texte sous forme normalisée KD définie par le Standard
Unicode <URL: http://www.unicode.org/reports/tr15/ >. En très gros, ça
décompose au maximum les caractères sous forme de radical + caractères
combinants (ce qui permet justement d'enlever les caractères. La figure 3 de
l'URL que j'ai donnée me semble assez parlante.
open FILEHANDLE, $file; binmode FILEHANDLE, ":encoding(iso-8859-1");
Deux petites remarques ici :
- Si c'est un fichier qu'on ouvre (par opposition à un fichier déjà ouvert, ou une socket, ou...), on peut faire le binmode à l'ouverture, avec la forme à trois arguments (qui est de toutes façons préférable) :
open FILEHANDLE, "<:encoding(iso-8859-1)", $file;
- Puisque c'est du Perl récent, on peut utiliser l'autovivification des scalaires pour les filehandles :
open my $filehandle, ...;
et utiliser $filehandle partout à la place de FILEHANDLE. Cette manière d'écrire présente de nombreux avantages.
- Y a t-il moyen de vérifier et adapter le binmode() en fonction du codage en entrée ?
Tu veux dire : essayer de détecter automatiquement l'encodage parmi quelques uns plausibles ? C'est techniquement plus ou moins possible, mais ça présente pas mal de complications, et en particulier le fait de lire un bout du fichier avant de faire le binmode, et donc de réinjecter le texte dans le fichier si on veut un vrai fichier. Il y a un module Encoding::Detect sur le CPAN, mais je ne sais pas s'il marche bien.
- a quoi correspond la méthode de normalisation KD du module Unicode ?
Ça convertit le texte sous forme normalisée KD définie par le Standard Unicode <URL: http://www.unicode.org/reports/tr15/ >. En très gros, ça décompose au maximum les caractères sous forme de radical + caractères combinants (ce qui permet justement d'enlever les caractères. La figure 3 de l'URL que j'ai donnée me semble assez parlante.
ctobini
Bonjour à tous,
Je reviens un petit peu en arrière, je me suis apperçu qu'il y avait un petit problème : avec la méthode :
open FILEHANDLE, $file; binmode FILEHANDLE ":encoding (iso-8859-1)"; stockage des lignes dans un @tableau ... close FILEHANDLE;
open OUT, ">>$out"; foreach (@tableau) { print OUT encode('iso-8859-1', $_) } print OUT }
J'ai les caractères du symbole 'micro' (comme pour microgramme) qui apparaissent comme des '?'.
Par ailleurs, en ouvrant un filehandle de sortie :
open OUT, '>utf8', $out ça marche bien. Tandis que open OUT, '>iso-8859-1', $out me renvoie une erreur de layout I/O
Merci si vous pouvez m'aider.
C. Tobini
Bonjour à tous,
Je reviens un petit peu en arrière, je me suis apperçu qu'il y avait
un petit problème : avec la méthode :
open FILEHANDLE, $file;
binmode FILEHANDLE ":encoding (iso-8859-1)";
stockage des lignes dans un @tableau
...
close FILEHANDLE;
open OUT, ">>$out";
foreach (@tableau) { print OUT encode('iso-8859-1', $_) }
print OUT
}
J'ai les caractères du symbole 'micro' (comme pour microgramme) qui
apparaissent comme des '?'.
Par ailleurs, en ouvrant un filehandle de sortie :
open OUT, '>utf8', $out ça marche bien.
Tandis que open OUT, '>iso-8859-1', $out me renvoie une erreur de
layout I/O
Je reviens un petit peu en arrière, je me suis apperçu qu'il y avait un petit problème : avec la méthode :
open FILEHANDLE, $file; binmode FILEHANDLE ":encoding (iso-8859-1)"; stockage des lignes dans un @tableau ... close FILEHANDLE;
open OUT, ">>$out"; foreach (@tableau) { print OUT encode('iso-8859-1', $_) } print OUT }
J'ai les caractères du symbole 'micro' (comme pour microgramme) qui apparaissent comme des '?'.
Par ailleurs, en ouvrant un filehandle de sortie :
open OUT, '>utf8', $out ça marche bien. Tandis que open OUT, '>iso-8859-1', $out me renvoie une erreur de layout I/O
Merci si vous pouvez m'aider.
C. Tobini
Paul Gaborit
À (at) 30 Jan 2006 05:26:31 -0800, "ctobini" écrivait (wrote):
Je reviens un petit peu en arrière, je me suis apperçu qu'il y avait un petit problème : avec la méthode :
open FILEHANDLE, $file; binmode FILEHANDLE ":encoding (iso-8859-1)"; stockage des lignes dans un @tableau ... close FILEHANDLE;
open OUT, ">>$out"; foreach (@tableau) { print OUT encode('iso-8859-1', $_) } print OUT }
J'ai les caractères du symbole 'micro' (comme pour microgramme) qui apparaissent comme des '?'.
Sans connaître le code exact du caractère posant problème, c'est dur de vous aider...
Par ailleurs, en ouvrant un filehandle de sortie :
open OUT, '>utf8', $out ça marche bien.
Plutôt '>:utf8'...
Tandis que open OUT, '>iso-8859-1', $out me renvoie une erreur de layout I/O
Lisez PerlIO et PerlIO::encoding : 'utf-8' est un 'layer' standard alors que 'iso-8859-1' est un 'custom layer'. Il faut donc utiliser '>:encoding(iso-8859-1)' (ce que vous avez déjà fait dans le code ci-dessus mais en lecture).
-- Paul Gaborit - <http://perso.enstimac.fr/~gaborit/> Perl en français - <http://perl.enstimac.fr/>
À (at) 30 Jan 2006 05:26:31 -0800,
"ctobini" <ctemp2@free.fr> écrivait (wrote):
Je reviens un petit peu en arrière, je me suis apperçu qu'il y avait
un petit problème : avec la méthode :
open FILEHANDLE, $file;
binmode FILEHANDLE ":encoding (iso-8859-1)";
stockage des lignes dans un @tableau
...
close FILEHANDLE;
open OUT, ">>$out";
foreach (@tableau) { print OUT encode('iso-8859-1', $_) }
print OUT
}
J'ai les caractères du symbole 'micro' (comme pour microgramme) qui
apparaissent comme des '?'.
Sans connaître le code exact du caractère posant problème, c'est dur
de vous aider...
Par ailleurs, en ouvrant un filehandle de sortie :
open OUT, '>utf8', $out ça marche bien.
Plutôt '>:utf8'...
Tandis que open OUT, '>iso-8859-1', $out me renvoie une erreur de
layout I/O
Lisez PerlIO et PerlIO::encoding : 'utf-8' est un 'layer' standard
alors que 'iso-8859-1' est un 'custom layer'. Il faut donc utiliser
'>:encoding(iso-8859-1)' (ce que vous avez déjà fait dans le code
ci-dessus mais en lecture).
--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>
À (at) 30 Jan 2006 05:26:31 -0800, "ctobini" écrivait (wrote):
Je reviens un petit peu en arrière, je me suis apperçu qu'il y avait un petit problème : avec la méthode :
open FILEHANDLE, $file; binmode FILEHANDLE ":encoding (iso-8859-1)"; stockage des lignes dans un @tableau ... close FILEHANDLE;
open OUT, ">>$out"; foreach (@tableau) { print OUT encode('iso-8859-1', $_) } print OUT }
J'ai les caractères du symbole 'micro' (comme pour microgramme) qui apparaissent comme des '?'.
Sans connaître le code exact du caractère posant problème, c'est dur de vous aider...
Par ailleurs, en ouvrant un filehandle de sortie :
open OUT, '>utf8', $out ça marche bien.
Plutôt '>:utf8'...
Tandis que open OUT, '>iso-8859-1', $out me renvoie une erreur de layout I/O
Lisez PerlIO et PerlIO::encoding : 'utf-8' est un 'layer' standard alors que 'iso-8859-1' est un 'custom layer'. Il faut donc utiliser '>:encoding(iso-8859-1)' (ce que vous avez déjà fait dans le code ci-dessus mais en lecture).
-- Paul Gaborit - <http://perso.enstimac.fr/~gaborit/> Perl en français - <http://perl.enstimac.fr/>
ctobini
Bonjour,
J'ai donc utilisé :
open OUT, ">:encoding(iso-8859-1)", $out; print OUT ... close OUT;
J'ai une erreur :
"x{03bc}" does not map to iso-8859-1 at a.pl line 332, je suppose que c'est le fameux caractère 'micro'.
A noter que, comme conseillé dans ce même post, j'ai utilisé Unicode::Normalize::NFKD afin d'éliminer les carcatères accentués.
C. Tobini
Bonjour,
J'ai donc utilisé :
open OUT, ">:encoding(iso-8859-1)", $out;
print OUT ...
close OUT;
J'ai une erreur :
"x{03bc}" does not map to iso-8859-1 at a.pl line 332, je suppose que
c'est le fameux caractère 'micro'.
A noter que, comme conseillé dans ce même post, j'ai utilisé
Unicode::Normalize::NFKD afin d'éliminer les carcatères accentués.