OVH Cloud OVH Cloud

encodage...

16 réponses
Avatar
kurtz le pirate
bonsoir,

avant d'essayer de faire un script pour décoder un fichier 'ansel' en
'ascii', je voulais savoir si ça existait déjà en perl un peux comme
quand on écrit :

open ($InputFile, "<:utf8", "toto.txt")

j'ai pas trouver d'infos à ce sujet.
merci

6 réponses

1 2
Avatar
Paul Gaborit
À (at) Fri, 22 Jul 2005 10:45:00 +0200,
"kurtz_le_pirate" écrivait (wrote):
donc avec un truc du genre :
-------------------------------------------------------------
my $srcfile = "toto.txt";
my $dstfile = "tata.txt";
my $line;

my %ANSEL_to_LATIN1 = (
'áa' => 'à',
...
);
my $ansel_regex = join "|", keys sort %ANSEL_to_LATIN1;

open(SRC, $srcfile);
open(DST, $dstfile);

while($line=<SRC>) {
$line =~ s/($ansel_regex)/$ANSEL_to_LATIN1{$1}/ge;
# $line =~ s/(Q$ansel_regexE)/$ANSEL_to_LATIN1{$1}/ge;
print DST $line;
)

close(DST);
close(SRC);

--------------------------------------------------------------
ca devrait le faire non ?


Presque... Le bug est maintenant sur les 'open' (vous ne spécifiez pas
si vous ouvrez le fichier en lecture ou en écriture). Je suppose que
vous utilisez une version récente de Perl (5.8.x). Dans ce cas vos
deux lignes 'open' doivent s'écrire :

open SRC, "<", $srcfile or die "Can't read file '$srcfile': $!n";
open DST, ">", $dstfile or die "Can't write file '$dstfile': $!n";

Je vous conseille aussi d'ajouter les deux lignes suivantes au début
du script :

use strict;
use warnings;

Cela vous amènera à corriger le 'while' (et son /accolade/ fermante)
en :

while (my $line = <SRC>) {
...
}

Et voili...

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

Avatar
Michel Rodriguez
kurtz_le_pirate wrote:
"Michel Rodriguez" a écrit dans le message de news:
42df55cd$0$333$
| Paul Gaborit wrote:
| >
| > Une "bonne" méthode consiste à créer une table de hachage de
| > transformation et une regexp de reconnaissance générale :
| >
| > my %ANSEL_to_LATIN1 > | > (
| > 'áa' => 'à',
| > 'áe' => 'è',
| > # ...
| > # à compléter !
| > );
| > my $ansel_regex = join "|", keys sort %ANSEL_to_LATIN1;
| >
| > Puis à faire toutes les substitutions en une seule passe :
| >
| > $_[0] =~ s/($ansel_regex)/$ANSEL_to_LATIN1{$1}/ge;
| >
| > (ce code simple ne fonctionne que si les clés utilisées dans
| > %ANSEL_to_LATIN1 ne contiennent pas de caractères spéciaux pour
les
| > regexp ce qui sera le cas ici.)
| >
|
| Pour etre complet, si les cles contiennent des caracteres speciaux,
un
| simple Q E les de-specialisera:
|
| $_[0] =~ s/(Q$ansel_regexE)/$ANSEL_to_LATIN1{$1}/ge;
|
| --
| mirod

donc avec un truc du genre :
------------------------------------------------------------------------------
my $srcfile = "toto.txt";
my $dstfile = "tata.txt";
my $line;

my %ANSEL_to_LATIN1 = (
'áa' => 'à',
...
);
my $ansel_regex = join "|", keys sort %ANSEL_to_LATIN1;

open(SRC, $srcfile);
open(DST, $dstfile);

while($line=<SRC>) {
$line =~ s/($ansel_regex)/$ANSEL_to_LATIN1{$1}/ge;
# $line =~ s/(Q$ansel_regexE)/$ANSEL_to_LATIN1{$1}/ge;
print DST $line;
)

close(DST);
close(SRC);

------------------------------------------------------------------------------
ca devrait le faire non ?


En fait, dans ton cas, il y a peut etre plus efficace que de construire
une enorme regexp.
Mon serveur de news a jete le debut de la thread et je ne comprends rien
au standard ANSEL, mais si le standard est bien fait, un truc du genre
$line =~ s{([áè].)}{$ANSEL_to_LATIN1{$1} || $1}ge;

ou` tu remplace [áè] par la liste de tes modificateurs. Si le di-graphe
est inconnu tu le recuperes sans changement, sinon tu remplace par le
charactere qui va bieng.

Ca ne marche pas si le standard autorise quelque chose comme 'ááa' dans
ta chaine, qui serait a remplacer par áà.

Donc pour resumer, si ce que tu as ecrit marche et va assez vite, ne te
casses pas la tete, sinon sache que on doit pouvoir ameliorer les perfos.

--
mirod

Avatar
kurtz_le_pirate
"Paul Gaborit" a écrit dans le message
de news:
:
: À (at) Fri, 22 Jul 2005 10:45:00 +0200,
: "kurtz_le_pirate" écrivait (wrote):
: > donc avec un truc du genre :
: > -------------------------------------------------------------
: > my $srcfile = "toto.txt";
: > my $dstfile = "tata.txt";
: > my $line;
: >
: > my %ANSEL_to_LATIN1 = (
: > 'áa' => 'à',
: > ...
: > );
: > my $ansel_regex = join "|", keys sort %ANSEL_to_LATIN1;
: >
: > open(SRC, $srcfile);
: > open(DST, $dstfile);
: >
: > while($line=<SRC>) {
: > $line =~ s/($ansel_regex)/$ANSEL_to_LATIN1{$1}/ge;
: > # $line =~ s/(Q$ansel_regexE)/$ANSEL_to_LATIN1{$1}/ge;
: > print DST $line;
: > )
: >
: > close(DST);
: > close(SRC);
: >
: > --------------------------------------------------------------
: > ca devrait le faire non ?
:
: Presque... Le bug est maintenant sur les 'open' (vous ne spécifiez
pas
: si vous ouvrez le fichier en lecture ou en écriture). Je suppose que
: vous utilisez une version récente de Perl (5.8.x). Dans ce cas vos
: deux lignes 'open' doivent s'écrire :
:
: open SRC, "<", $srcfile or die "Can't read file '$srcfile': $!n";
: open DST, ">", $dstfile or die "Can't write file '$dstfile': $!n";
:
: Je vous conseille aussi d'ajouter les deux lignes suivantes au début
: du script :
:
: use strict;
: use warnings;
:
: Cela vous amènera à corriger le 'while' (et son /accolade/ fermante)
: en :
:
: while (my $line = <SRC>) {
: ...
: }

oui... c'est bien ce que j'avais à l'esprit: les angles, les
accolades, les -w... j'ai voulu faire simple et rapide :((
et j'ai fait vraiment trop rapide :))


merci encore
Avatar
kurtz le pirate
In article ,
Paul Gaborit wrote:

:: ...
:: my $ansel_regex = join "|", keys sort %ANSEL_to_LATIN1;
:: ...

my %ANSEL_to_LATIN1 = (
'áa' => '',
'áe' => 'è ',
...
);
my $ansel_regex = join "|", keys sort %ANSEL_to_LATIN1;


error line 51:
Type of arg 1 to keys must be hash (not sort) near "%ANSEL_to_LATIN1;"


c'est quoi cette erreur ? :((

merci paul...
Avatar
Michel Rodriguez
kurtz le pirate wrote:
In article ,
Paul Gaborit wrote:

:: ...
:: my $ansel_regex = join "|", keys sort %ANSEL_to_LATIN1;
:: ...

my %ANSEL_to_LATIN1 = (
'áa' => '',
'áe' => 'è ',
...
);
my $ansel_regex = join "|", keys sort %ANSEL_to_LATIN1;


error line 51:
Type of arg 1 to keys must be hash (not sort) near "%ANSEL_to_LATIN1;"


c'est quoi cette erreur ? :((


L'erreur c'est que tu dois faire sort keys %ANSEL_to_LATIN1, ou plus
simplement keys %ANSEL_to_LATIN1, le sort ne sert pas a grand chose dans
ton cas.

sort demande un tableau en entree, fournit par keys %ANSEL_to_LATIN1

--
mirod

Avatar
kurtz le pirate
In article <42e14903$0$329$,
Michel Rodriguez wrote:

::kurtz le pirate wrote:
::> In article ,
::> Paul Gaborit wrote:
::>
::> :: ...
::> :: my $ansel_regex = join "|", keys sort %ANSEL_to_LATIN1;
::> :: ...
::>
::> my %ANSEL_to_LATIN1 = (
::> 'áa' => '',
::> 'áe' => 'è ',
::> ...
::> );
::> my $ansel_regex = join "|", keys sort %ANSEL_to_LATIN1;
::>
::>
::> error line 51:
::> Type of arg 1 to keys must be hash (not sort) near "%ANSEL_to_LATIN1;"
::>
::>
::> c'est quoi cette erreur ? :((
::
::L'erreur c'est que tu dois faire sort keys %ANSEL_to_LATIN1, ou plus
::simplement keys %ANSEL_to_LATIN1, le sort ne sert pas a grand chose dans
::ton cas.
::
::sort demande un tableau en entree, fournit par keys %ANSEL_to_LATIN1

merci bien.

j'ai eu une autre galère avec le codage des caractères. dans vi et dans
bbedit ça ne donne pas la même chose et la convertion ne fonctionnait
pas. mais la je m'en suis sortie tout seul (pour une fois) en
construisant le hash comme ça :
my %ANSEL_to_LATIN1 = (
pack('CC',0xE1,0x61) => 'à',
pack('CC',0xE2,0x65) => 'é',
...


un grand merci a vous tous !!!
1 2