perluniintro - Introduction à l'utilisation d'Unicode en Perl



NAME/NOM

perluniintro - Introduction à l'utilisation d'Unicode en Perl


DESCRIPTION

Ce document donne une idée générale d'Unicode et de son utilisation en Perl.

Unicode

Unicode est un jeu de caractères standardisé qui prévoit de codifier tous les systèmes d'écriture existant de par le monde ainsi que de nombreux autres symboles.

Unicode et ISO/IEC 10646 sont des normes qui attribuent un code pour les caractères de tous les jeux de caractères modernes, couvrant plus de 30 systèmes d'écriture et des centaines de langues, incluant toutes les langues modernes commercialement importantes. Tous les caractères chinois, japonais et cooréens en font aussi parti. Ces standards prévoient de couvrir tous les caractères de plus de 250 systèmes d'écriture et de milliers de langues. Unicode 1.0 est sorti en octobre 1991 et et sa version 4.0 en avril 2003.

Un caractère Unicode est une entité abstraite. Il n'est lié à aucune taille d'entier en particulier et encore moins au type char du language C. Unicode est neutre vis à vis de la langue et de l'affichage : il ne code pas la langue utilisée par le texte et ne définit pas de polices ou d'autres aspects de présentation graphique. Unicode concerne les caractères et le texte composé de ces caractères.

Unicode définit des caractères comme LATIN CAPITAL LETTER A ou GREEK SMALL LETTER ALPHA et un nombre unique pour chacun de ces caractères, en l'occurence respectivement 0x0041 et 0x03B1. Ces nombres uniques sont appelés points de code ou plus simplement numéros de caractères.

Le standard Unicode préfère la notation hexadécimale pour les numéros de caractères. Si des nombres tels que 0x0041 ne vous sont pas familiers, jetez un oeil à la section « Notation hexadécimale ». Le standard Unicode utilise la notation U+0041 LATIN CAPITAL LETTER A pour donner le numéro hexadécimal du caractère suivi de son nom normalisé.

Unicode définit aussi différentes propriétés pour les caractères, telles que ``uppercase'' (majuscule) ou ``lowercase'' (minuscule), ``decimal digit'' (chiffre décimal) ou ``punctuation'' (ponctuation) ; ces propriétés étant indépendantes du nom des caractères. En outre, sont définies plusieurs opérations sur les caractères telles que ``passer en majuscule'', ``passer en minuscule'' et ``trier''.

Un caractère Unicode est constitué soit d'un unique caractère, soit d'un caractère de base (tel que LATIN CAPITAL LETTER A) suivi d'un ou plusieurs modificateurs ou caractères combinatoires (tel que COMBINING ACUTE ACCENT). Cette séquence composée d'un caractère de base suivi de ses modificateurs est appelée une séquence combinante.

Le fait de considérer ces séquences comme étant un ``caractère'' dépend de votre point de vue. En tant que programmeur, vous aurez plutôt tendance à considérer chaque élément de la séquence pris séparément. Alors qu'un utilisateur considérera probablement la séquence complète comme étant un unique ``caractère'' car c'est de cette manière qu'il est perçu dans sa langue.

Avec la vision globale, déterminer le nombre total de caractères est difficile. Mais avec le point de vue du programmeur (chaque caractère, qu'il soit de base ou combinatoire, est un caractère), le concept de nombre de caractères est plus déterministe. Dans ce document, nous adopterons ce second point de vue : un ``caractère'' est un point de code Unicode, que ce soit un caractère de base ou un caractère combinatoire.

Pour certaines combinaisons, il existe des caractères précomposés. Par exemple LATIN CAPITAL LETTER A WITH ACUTE est défini comme un point de code unique. Ces caractères précomposés ne sont disponibles que pour certaines combinaisons et le sont principalement pour faciliter la conversion entre Unicode et les anciens standards (tel que ISO 8859). De manière générale, la méthode par combinaison est plus extensible. Pour faciliter la conversion entre les différentes manières de composer un caractère, plusieurs formes de normalisation sont définies dans le but de standardiser les représentations.

Pour des raisons de compatibilité avec les anciens systèmes de codage, l'idée ``un numéro unique pour chaque caractère'' est un peu remise en cause : en fait, il y a ``au moins un numéro pour chaque caractère''. Un même caractère peut être représenté différemment dans plusieurs anciens systèmes d'encodage. De même certains points de code ne correspondent à aucun caractère. En effet, d'une part, des blocs déjà utilisés contiennent des points de code non alloués. Et d'autre part, dans Unicode, on trouve des caractères de contrôle (ou de commande) et des caractères spéciaux qui ne représentent pas de vrais caractères.

Un mythe courant concernant Unicode est que celui-ci serait ``16 bits'' car il n'existe que 0x10000 (ou 65536) caractères entre 0x0000 et 0xFFFF. Ceci est faux. Depuis Unicode 2.0 (juillet 1996), Unicode utilise 21 bits (0x10FFFF) et depuis Unicode 3.1 (mars 2001), des caractères ont été définis au-delà de 0xFFFF. Les 0x10000 premiers caractères sont appellés plan 0, ou encore plan multilingue de base (PMP -- ou BMP en anglais). Avec Unicode 3.1, c'est 17 (oui, dix-sept) plans qui ont été définis mais ils ne sont pas tous entièrement remplis, du moins pour le moment.

Un autre mythe est qu'il existerait une corrélation entre les langues et les blocs de 256 caractères, chaque bloc définissant les caractères utilisés par une langue ou un ensemble de langues. Ceci est tout aussi faux. Cette division en bloc existe, mais elle est presque totalement accidentelle, un simple artéfact de la manière dont les caractères ont été et continuent à être alloués. En revanche, il existe le concept d'écriture (ou script en anglais) qui est plus utile : il existe une écriture latine, une grecque et ainsi de suite. Les écritures sont généralement réparties sur plusieurs blocs. Pour plus d'information consultez la page de manuel Unicode::UCD.

Les point de code Unicode ne sont que des nombres abstraits. Pour recevoir ou émettre ces nombres abstraits, ils faut les encoder ou les sérialiser d'une manière ou d'une autre. Unicode définit plusieurs formes d'encodage, parmi lesquelles UTF-8 est peut-être la plus populaire. UTF-8 est méthode d'encodage à taille variable qui encode les caractères Unicode sur 1 à 6 octets (maximum 4 pour les caractères actuellement définis). Les autres méthodes incluent UTF-16, UTF-32 et leur variantes grand-boutistes et petit-boutistes (UTF-8 est indépendant de l'ordre des octets). L'ISO/IEC définit aussi les formes UCS-2 et UCS-4.

Pour plus d'information à propos de l'encodage, par exemple pour savoir à quoi correspondent les caractères de substitution (surrogates) et les marques d'ordre d'octets (byte order marks ou BOMs), consultez perlunicode.

Le support d'Unicode en Perl

À partir de la version 5.6.0, Perl était apte à gérer Unicode nativement. Mais la version 5.8.0 a été la première version recommandée pour pouvoir travailler sérieusement avec Unicode. La version de maintenance 5.6.1 a corrigé un grand nombre des problèmes de l'implémentation initiale, mais par exemple, les expressions rationnelles ne fonctionnaient toujours pas en Unicode dans la version 5.6.1.

À partir de Perl 5.8.0, l'utilisation de use utf8 n'est plus nécessaire. Dans les versions précédentes le pragma utf8 était utilisé pour déclarer que les opérations du bloc ou du fichier courant étaient compatibles Unicode. Ce modèle s'avéra mauvais, ou tout du moins maladroit : la caractéristique ``Unicode'' est maintenant liée aux données et non plus aux opérations. L'utilisation de use utf8 ne reste nécessaire que dans un seul cas : lorsque le script Perl est lui-même encodé en UTF-8. Cele vous permet alors d'utiliser l'UTF-8 pour vos identifiants ainsi que dans les chaînes de caractères et les expressions rationnelles. Ceci n'est pas le règlage par défaut, car sinon les scripts comportant des données encodées en 8 bits risqueraient de ne plus fonctionner. Consultez utf8.

Le modèle Unicode de Perl

Perl supporte aussi bien les chaînes de caractères utilisant l'encodage pré-5.6 sur huit bits natifs que celles utilisant des caractères Unicode. Le principe est que Perl essaye au maximum de conserver les données avec l'encodage 8 bits, mais dès que Unicode devient indispensable, les données sont converties en Unicode de manière transparente.

En interne, Perl utilise le jeu de caractères natif sur 8 bit de la plateforme (par exemple Latin-1) et pour encoder les chaines de caractères Unicode, il utilise par défaut UTF-8. Plus précisement, si tous les points de codes d'une chaîne sont inférieurs ou égal à 0xFF, Perl utilisera l'encodage sur 8 bits natif. Sinon, il utilisera UTF-8.

En général, l'utilisateur de Perl n'a besoin ni de savoir ni de se préoccuper de la manière dont Perl encode ses chaînes de caractères en interne, mais cela peut devenir utile lorsqu'on envoie des chaînes Unicode dans un flux n'utilisant pas PerlIO (il utilisera donc l'encodage par ``défaut''). Dans ce cas, les octets bruts utilisés en interne (reposant sur le jeu de caractères natif ou sur UTF-8, selon les chaînes) seront transmis et un avertissement ``Wide character'' sera émis pour les chaînes contenant un caractère dépassant 0x00FF.

Par exemple,

      perl -e 'print "\x{DF}\n", "\x{0100}\x{DF}\n"'

produit un mélange plutôt inutile de caractères natifs et d'UTF-8 ainsi que l'avertissement :

     Wide character in print at ...

Pour afficher de l'UTF-8, il faut utiliser la couche :utf8. L'ajout de :

      binmode(STDOUT, ":utf8");

au début de ce programme d'exemple forcera l'affichage à être en totalité en UTF-8 et retirera les avertissements.

Vous pouvez automatiser l'utilisation de l'UTF-8 pour vos entrées/sorties standard, pour les appels à open() et pour @ARGV en utilisant l'option -C de la ligne de commande ou la variable d'environnement PERL_UNICODE. Consultez la page de manuel perlrun pour la documentation de l'option -C.

Notez que cela signifie que Perl espère que les autres logiciels fonctionnent eux-aussi en UTF-8 : si Perl est amené à croire que STDIN est en UTF-8 alors que STDIN provient d'une commande qui n'est pas en UTF-8, Perl se plaindra de caractères UTF-8 mal composés.

Toutes les fonctionnalités qui combinent Unicode et les E/S (I/O) nécessitent l'usage de la nouvelle fonctionnalité PerlIO. La quasi totalité des plateformes Perl 5.8 utilise PerlIO mais vous pouvez le vérifier en lancant la commande ``perl -V'' et en recherchant useperlio=define.

Unicode et EBCDIC

Perl 5.8.0 supporte aussi Unicode sur les plateformes EBCDIC. Le support d'Unicode y est plus complexe à implémenter car il nécessite des conversions supplémentaires à chaque utilisation. Certains problèmes persistent ; consultez perlebcdic pour plus de détails.

Dans tous les cas, le support actuel d'Unicode sur les plateformes EBCDIC est bien meilleur que dans les versions 5.6 (cela ne fonctionnait quasiment pas sur les plateformes EBCDIC). Sur ces plateformes, l'encodage interne est UTF-EBCDIC au lieu d'UTF-8. La différence est que UTF-8 est ``ASCII-sûr'' dans le sens où les caractères ASCII sont codés tels quels en UTF-8, alors que UTF-EBCDIC est ``EBCDIC-sûr''.

Créer de l'Unicode

Dans les littéraux, pour créer des caractères Unicode dont le point de code est supérieur à 0xFF, il faut utiliser la notation \x{...} dans une chaîne entre guillemet :

    my $smiley = "\x{263a}";

De la même façon, cette notation peut être utilisée dans les expressions rationnelles :

    $smiley =~ /\x{263a}/;

À l'exécution vous pouvez utiliser chr():

    my $hebrew_alef = chr(0x05d0);

Consultez « Autres ressources » pour savoir comment trouver ces codes numériques.

Évidemment, ord() fera l'inverse : il transformera un caractère en un point de code.

Notez que \x.. (sans {} et avec seulement deux chiffres hexadécimaux), \x{...} ainsi que chr(...) génèrent un caractère sur un octet pour les arguments inférieurs à 0x100 (256 en décimal) et ceci pour conserver une compatibilité ascendante avec les anciennes versions de Perl. Pour les arguments supérieurs à 0xFF, il s'agira toujours de caractères Unicode. Si vous voulez forcer la génération de caractères Unicode quelle que soit la valeur, utilisez pack("U",...) au lieu de \x.., \x{...}, ou chr().

Vous pouvez aussi utiliser le pragma charnames pour invoquer les caractères par leur nom entre guillemets :

    use charnames ':full';
    my $arabic_alef = "\N{ARABIC LETTER ALEF}";

Et, comme indiquer précédement, vous pouvez aussi utiliser la fonction pack() pour produire des caractères Unicode :

   my $georgian_an  = pack("U", 0x10a0);

Notez que \x{...} et \N{...} sont des constantes : vous ne pouvez pas utiliser de variables dans ces notations. Si vous voulez un équivalent dynamique, utilisez chr() et charnames::vianame().

Si vous voulez forcer un résultat en caractères Unicode, utilisez le préfixe spécial "U0". Il ne consomme pas d'argument mais force, dans le résultat, l'utilisation de caractères Unicode à la place d'octets.

   my $chars = pack("U0C*", 0x80, 0x42);

De la même manière, vous pouvez forcer l'utilisation d'octets par le préfixe spécial "C0".

Manipuler l'Unicode

La manipulation d'Unicode est quasi transparente : il suffit d'utiliser les chaînes de caractères comme d'habitude. Les fonctions comme index(), length(), et substr() fonctionneront avec des caractères Unicode et il en sera de même avec les expressions rationnelles (consultez perlunicode et la page de manuel perlretut).

Notez que Perl considère les séquences combinantes comme étant composées de caractères séparés, par exemple :

    use charnames ':full';
    print length("\N{LATIN CAPITAL LETTER A}\N{COMBINING ACUTE ACCENT}"), "\n";

affichera 2 et non 1. La seule exception est l'utilisation de \X dans les expressions rationnelles pour reconnaître une séquence combinante de caractères.

En revanche, les choses ne sont malheureusement pas toujours aussi transparentes que ce soit avec l'encodage natif, avec les E/S ou dans certaines situations spéciales. C'est que nous allons détaillé maintenant.

Encodages natifs

Lorsque vous utilisez conjointement des données natives et des données Unicode, les donnés natives doivent être converties en Unicode. Par défaut ISO 8859-1 (ou EBCDIC selon le cas) est utilisé. Vous pouvez modifier ce comportement en utilisant le pragma encoding, par exemple :

    use encoding 'latin2'; # ISO 8859-2

Dans ce cas, les littéraux (chaînes et expressions rationnelles), chr() et ord() produiront de l'Unicode en supposant un codage initiale en ISO 8859-2. Notez que le nom de l'encodage est reconnu de manière indulgente : au lieu de latin2 on aurait pu utiliser Latin2, ou iso8859-2 ou encore d'autres variantes. En utilisant seulement :

    use encoding;

la valeur de la variable PERL_ENCODING sera alors utilisée. Si cette variable n'est pas positionnée, le pragma échouera.

Le module Encode connait de nombreux encodages et fournit une interface pour faire des conversions entre eux :

    use Encode 'decode';
    $data = decode("iso-8859-3", $data); # convertit du natif vers utf-8

Entrées/Sorties et Unicode

Normalement, l'affichage de données Unicode

    print FH $une_chaine_avec_unicode, "\n";

produit les octets bruts utilisés en interne par Perl pour encoder la chaîne Unicode. Le système d'encodage interne dépend du systèmes ainsi que des caractères présents dans la chaîne. S'il y a au moins un caractère ayant un code suppérieur ou égal à 0x100, vous obtiendrez un avertissement. Pour être sûr que la sortie utilise explicitement l'encodage que vous désirez, et pour éviter l'avertissement, ouvrez le flux avec l'encodage désiré. Quelques exemples :

    open FH, ">:utf8", "fichier";
    open FH, ">:encoding(ucs2)",      "fichier";
    open FH, ">:encoding(UTF-8)",     "fichier";
    open FH, ">:encoding(shift_jis)", "fichier";

et sur les flux déjà ouverts, utilisez binmode() :

    binmode(STDOUT, ":utf8");
    binmode(STDOUT, ":encoding(ucs2)");
    binmode(STDOUT, ":encoding(UTF-8)");
    binmode(STDOUT, ":encoding(shift_jis)");

Les noms d'encodages sont peu regardants : la casse n'a pas d'importance et beaucoup possèdent plusieurs alias. Notez par contre que le filtre :utf8 doit toujours être spécifiée exactement de cette manière ; il n'est pas reconnue de manière aussi permissive que les noms d'encodages.

Consultez PerlIO pour en savoir plus sur le filtre :utf8, la page de manuel PerlIO::encoding et la page de manuel Encode::PerlIO pour tout ce qui concerne le filtre :encoding() et la page de manuel Encode::Supported pour les nombreux encodages reconnus par le module Encode.

La lecture d'un fichier que vous savez être encodés en Unicode ou en natif ne convertira pas magiquement les données en Unicode aux yeux de Perl. Pour cela, spécifier la couche désirée à l'ouverture du fichier :

    open(my $fh,'<:utf8', 'anything');
    my $ligne_unicode = <$fh>;
    open(my $fh,'<:encoding(Big5)', 'anything');
    my $ligne_unicode = <$fh>;

Pour plus de flexibilité, le filtre E/S peut aussi être spécifié via le pragma open. Consultez open ou l'exemple suivant :

    use open ':utf8'; # les entrees et sorties seront par defaut en UTF-8
    open X, ">file";
    print X chr(0x100), "\n";
    close X;
    open Y, "<file";
    printf "%#x\n", ord(<Y>); # Cela devrait afficher 0x100
    close Y;

Avec le pragma open vous pouvez utiliser le filtre :locale :

    BEGIN { $ENV{LC_ALL} = $ENV{LANG} = 'ru_RU.KOI8-R' }
    # :locale va utiliser les variables d'environnements des locales comme LC_ALL
    use open OUT => ':locale'; # russki parusski
    open(O, ">koi8");
    print O chr(0x430); # Unicode CYRILLIC SMALL LETTER A = KOI8-R 0xc1
    close O;
    open(I, "<koi8");
    printf "%#x\n", ord(<I>), "\n"; # ceci devrais afficher 0xc1
    close I;

ou vous pouvez aussi utiliser le filtre ':encoding(...)' :

    open(my $epic,'<:encoding(iso-8859-7)','iliad.greek');
    my $ligne_unicode = <$epic>;

Ces méthodes installent, sur le flux d'entrée/sortie, un filtre transparent qui, lors de leur lecture à partir du flux, convertit les données depuis l'encodage spécifié. Le résultat est toujours de l'Unicode.

En instaurant un filtre par défaut, le pragma open impacte tous les appels à open() qui suivront. Si vous ne voulez modifier que certains flux, utilisez les filtres explicites directement dans les appels à open().

Vous pouvez modifier l'encodage d'un flux déjà ouvert en utilisant binmode() ; consultez binmode dans la page de manuel perlfunc.

Le filtre :locale ne peut pas, à l'heure actuelle (comme dans Perl 5.8.0), fonctionner avec open() et binmode() mais seulement avec le pragma open. Par contre :utf8 et :encoding(...) fonctinnent avec open(), binmode() et le pragma open.

De la même manière, vous pouvez utiliser les filtres d'E/S sur un flux en sortie pour convertir automatiquement depuis Unicode vers l'encodage spécifié, lors des écritures dans ce flux. Par exemple, le code suivant copie le contenu du fichier ``text.jis'' (encodé en ISO-2022-JP, autrement dit JIS) dans le fichier ``text.utf8'', encodé en UTF-8 :

    open(my $nihongo, '<:encoding(iso-2022-jp)', 'text.jis');
    open(my $unicode, '>:utf8',                  'text.utf8');
    while (<$nihongo>) { print $unicode $_ }

Les noms des encodages fournis à open() ou au pragma open, sont similaires à ceux du pragma encoding en ce qui concerne la flexibilité : koi8-r et KOI8R seront interprétés de la même manière.

Les encodages communément reconnus par l'ISO, en MIME ou par l'IANA et divers organismes de normalisation sont aussi Sreconnus ;> pour une liste plus détaillée consultez la page de manuel Encode::Supported.

La fonction read() lit des caractères et renvoie le nombre de caractère lus. Les fonctions seek() et tell() utilisent un nombre d'octets ainsi que sysread() et sysseek().

Notez qu'à cause du comportement par défaut qui consiste à ne pas faire de conversion si aucun filtre par défaut n'est défini, il est facile d'écrire du code qui fera grossir un fichier en ré-encodant les données déjà encodées :

    # ATTENTION CODE DEFECTUEUX
    open F, "file";
    local $/; ## lis l'ensemble du fichier sous forme de caractères 8 bits
    $t = <F>;
    close F;
    open F, ">:utf8", "file";
    print F $t; ## conversion en UTF-8 sur la sortie
    close F;

Si vous exécutez deux fois ce code, le contenu de file sera doublement encodé en UTF-8. L'utilisation de use open ':utf8' aurait permis d'éviter ce bug ou on aurait pu aussi ouvrir file explicitement en UTF-8.

NOTE: Les fonctionnalités :utf8 et :encoding ne fonctionnent que si votre Perl a été compilé avec la nouvelle fonctionnalité PerlIO (ce qui est le cas par défaut sur la plupart des systèmes).

Afficher de l'Unicode sous forme de texte

Il peut arriver que vous vouliez afficher des scalaires Perl contenant de l'Unicode comme un simple texte ASCII (ou EBCDIC). La sous-routine suivante convertit ses arguments de telle manière que les caractères Unicode dont le point de code est supérieur à 255 sont affichés sous la forme \x{...}, que les caractères de contrôle (comme \n) sont affichés sous la forme \x.. et que le reste est affiché sans conversion :

   sub nice_string {
       join("",
         map { $_ > 255 ?                  # Si caractère étendu ...
               sprintf("\\x{%04X}", $_) :  # \x{...}
               chr($_) =~ /[[:cntrl:]]/ ?  # Si caractère de contrôle ...
               sprintf("\\x%02X", $_) :    # \x..
               quotemeta(chr($_))          # Sinon sous forme quoted 
         } unpack("U*", $_[0]));           # Extrait les caractères Unicode
   }

Par exemple,

   nice_string("foo\x{100}bar\n")

renvoie la chaîne :

   'foo\x{0100}bar\x0A'

qui est prête à être imprimée.

Cas spéciaux

Sujets avancés

Divers

Questions/Réponses

Notation hexadécimale

Le standard Unicode privilégie la notation hexadécimale car cela montre plus clairement la division d'Unicode en blocs de 256 caractères. L'hexadécimal est aussi plus court que le décimal. Vous pouvez toujours utiliser la notation décimale, bien sûr, mais l'apprentissage de l'hexadécimal vous facilitera la vie avec le standard Unicode. La notation U+HHHH utilise l'hexadécimal, par exemple.

Le préfixe 0x indique un nombre hexadécimal, les chiffres étant 0 à 9 et a à f (ou A à F, la casse n'ayant pas d'importance). Chaque chiffre hexadécimal représente quatres bits, autrement dit la moitié d'un octet. print 0x..., "\n" affiche un nombre hexadécimal convertit en décimal et printf "%x\n", $decimal affiche un nombre décimal convertit en hexadécimal. Si vous n'avez que les ``chiffres'' d'un nombre hexadécimal, vous pouvez aussi utiliser la fonction hex().

    print 0x0009, "\n";    # 9
    print 0x000a, "\n";    # 10
    print 0x000f, "\n";    # 15
    print 0x0010, "\n";    # 16
    print 0x0011, "\n";    # 17
    print 0x0100, "\n";    # 256
    print 0x0041, "\n";    # 65
    printf "%x\n",  65;    # 41
    printf "%#x\n", 65;    # 0x41
    print hex("41"), "\n"; # 65

Autres ressources


UNICODE DANS LES VERSIONS DE PERL PLUS ANCIENNES

Si vous ne pouvez pas mettre à jour votre Perl en version 5.8.0 ou plus récente, vous pouvez toujours traiter de l'Unicode en utilisant les modules Unicode::String, Unicode::Map8, et Unicode::Map, disponibles sur le CPAN. Si vous avez installé GNU recode, vous pouvez aussi utiliser le front-end Perl Convert::Recode pour les conversions de caractères.

Les exemples suivants proposent une conversion rapide d'octets ISO 8859-1 (Latin-1) en octets UTF-8 et inversement, ce code fonctionnant aussi avec les versions plus anciennes de Perl 5.

    # ISO 8859-1 vers UTF-8
    s/([\x80-\xFF])/chr(0xC0|ord($1)>>6).chr(0x80|ord($1)&0x3F)/eg;
    # UTF-8 vers ISO 8859-1
    s/([\xC2\xC3])([\x80-\xBF])/chr(ord($1)<<6&0xC0|ord($2)&0x3F)/eg;


REFERENCES

perlunicode, Encode, encoding, open, utf8, bytes, la page de manuel perlretut, la page de manuel perlrun, la page de manuel Unicode::Collate, la page de manuel Unicode::Normalize et la page de manuel Unicode::UCD.


REMERCIEMENTS

Merci aux lecteurs des listes de diffusion perl5-porters@perl.org, perl-unicode@perl.org, linux-utf8@nl.linux.org et unicore@unicode.org pour leurs commentaires précieux.


AUTEUR, COPYRIGHT, ET LICENCE

Copyright 2001-2002 Jarkko Hietaniemi <jhi@iki.fi>

Ce document peut être distribué sous les mêmes conditions que Perl lui-même.


TRADUCTION

Version

Cette traduction française correspond à la version anglaise distribuée avec perl 5.8.8. Pour en savoir plus concernant ces traductions, consultez http://perl.enstimac.fr/.

Traducteur

Marc Carmier <mcarmier@gmail.com>.

Relecture

Paul Gaborit (Paul.Gaborit arobase enstimac.fr).