Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Substitution et caractères accentués ?

16 réponses
Avatar
ctobini
Bonjour,

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.

Sauriez-vous comment faire cette manipulation ?

En vous remerciant.

C=2E Tobini

10 réponses

1 2
Avatar
Nicolas George
"ctobini" wrote in message
:
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).

Avatar
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. :

use locale 'fr' ;

cf. http://perldoc.perl.org/perllocale.html#The-use-locale-pragma

Avatar
Nicolas George
Antoun wrote in message <43d6b628$0$16233$:
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.

Avatar
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
Avatar
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/>

Avatar
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.

Avatar
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
Avatar
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/>

Avatar
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
Avatar
Paul Gaborit
À (at) 30 Jan 2006 06:01:47 -0800,
"ctobini" écrivait (wrote):
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'.


Exact :

03BC µ LETTRE MINUSCULE GRECQUE MU

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

1 2