IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

Remplir un Hash et le comprarer avec un autre Hash


Sujet :

Langage Perl

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Femme Profil pro
    Inscrit en
    Janvier 2013
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Femme

    Informations forums :
    Inscription : Janvier 2013
    Messages : 53
    Par défaut Remplir un Hash et le comprarer avec un autre Hash
    Bonjour,
    J'ai un programme qui fait la segmentation des mots arabe en caractères et le stockage de ces caractères se fait dans un Hash (h).
    -Le premier problème est l'ordre des caractères n'est pas le même que leur ordre d’apparition dans le mot
    -Le deuxième problème j'aimerais faire la comparaison avec un autre hash (Regles) qui contient pour chaque graphème son remplacement (phonème)
    Voici le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
     
    use utf8;
    use File::Spec;	
     
     
    my $RepBase ='C:\\Users\\lenovo\\Desktop\\Memoire Mastere\\Script\\Script_final\\Script_Grapheme-phoneme\\tous les scripts\\ScriptV';
    my $FicAraIn  = File::Spec->catfile( $RepBase, 'corpusHash.txt' );
    open ( IN_Ara, '<:encoding(UTF-8)', $FicAraIn ) or die "Impossible ouvrir fichier $FicAraIn en lecture\n";
    my $FicAraOut1 = File::Spec->catfile( $RepBase, 'SortieHash.txt' );
    open my $fh_Aran, '>', $FicAraOut1  or die "Impossible ouvrir fichier $FicAraOut1 en sortie\n";
     
     
    #Déclaration des fichiers Xml: 
    my $FichierReglePhonetique ='C:\\Users\\lenovo\\Desktop\\Memoire Mastere\\Script\\Script_final\\Script_Grapheme-phoneme\\tous les scripts\\ScriptV\\RegleDePhonetisation.xml';
    my $FichierBAseException ='C:\\Users\\lenovo\\Desktop\\Memoire Mastere\\Script\\Script_final\\Script_Grapheme-phoneme\\tous les scripts\\ScriptV\\BaseException.xml';
    my $FichierBAseNombre ='C:\\Users\\lenovo\\Desktop\\Memoire Mastere\\Script\\Script_final\\Script_Grapheme-phoneme\\tous les scripts\\ScriptV\\BaseNombre.xml';
    my $FichierBAseDouble ='C:\\Users\\lenovo\\Desktop\\Memoire Mastere\\Script\\Script_final\\Script_Grapheme-phoneme\\tous les scripts\\ScriptV\\BaseException1.xml';
    my $FichierBAseEtrangers ='C:\\Users\\lenovo\\Desktop\\Memoire Mastere\\Script\\Script_final\\Script_Grapheme-phoneme\\tous les scripts\\ScriptV\\BaseExceptionMotsEtrangers.xml';
     
     
    my $phoneme;
    my $phoneme1="";
    my $phoneme2="";
    my $phonemeN="";
    my $phonemeD="";
    my $phonemeE="";
    my $phonemeq="";
    my $phonemealif="";
    my %exceptions;
    my %nombre;
    my %alif;
    my %doublepro;
    my %etrangers;
    my $graph;
    my $cg;
     
    open my $EXC, "<", $FichierBAseException or die "Ouverture impossible du fichier $FichierBAseException $! \n";
    while (<$EXC>) 
    {
    	$graph = $1 if /<Grapheme>([^<]+)<\/Grapheme>/;
    	if ( /<Phoneme>([^<]+)<\/Phoneme>/ ) 
    	{
    		$exceptions{$graph} = $1;
     
    	}
    }
    close $EXC;
     
    open my $DOUBLE, "<", $FichierBAseDouble or die "Ouverture impossible du fichier $FichierBAseException $! \n";
    while (<$DOUBLE>) 
    {
    	$graph = $1 if /<Grapheme>([^<]+)<\/Grapheme>/;
    	if ( /<Phoneme>([^<]+)<\/Phoneme>/ ) 
    	{
    		$doublepro{$graph} = $1;
     
    	}
    }
    close $DOUBLE;
     
    open my $ETRANGER, "<", $FichierBAseEtrangers or die "Ouverture impossible du fichier $FichierBAseException $! \n";
    while (<$ETRANGER>) 
    {
    	$graph = $1 if /<Grapheme>([^<]+)<\/Grapheme>/;
    	if ( /<Phoneme>([^<]+)<\/Phoneme>/ ) 
    	{
    		$etrangers{$graph} = $1;
     
    	}
    }
    close $ETRANGER;
     
     
    open my $NBR, "<", $FichierBAseNombre or die "Ouverture impossible du fichier $FichierBAseException $! \n";
    while (<$NBR>) 
    {
    	$graph = $1 if /<Grapheme>([^<]+)<\/Grapheme>/;
     
    		$nombre{$graph} = $1;
     
     
    }
    close $NBR;
    # les exceptions sont maintenant chargées dans le hash %exceptions. Continuer en lisant le fichier des régles
     
    my %regles;
    my ($graph, $cd, $cg);
     
    open my $RULES, "<", $FichierReglePhonetique or die "Ouverture impossible du fichier $FichierReglePhonetique $! \n";
    while (<$RULES>) {
    	$cd = $1 if /<Composant Nom="C-Droit" Utilite="Oui">([^<]+)<\/Composant>/; # $cd sera undef si utilite = non
    	$graph = $1 if /<Composant Nom="Graph">([^<]+)<\/Composant>/;
    	$cg = $1 if /<Composant Nom="C-Gauche" Utilite="Oui">([^<]+)<\/Composant>/;
    	if ( /<Composant Nom="Remplacement">([^<]+)<\/Composant>/ ) 
    	{
    		my $repl = $1;
    		# on va créer une clef de hash en concaténant $cd, $cg et $graph (avec séparateur) si ces élements sont définis
    		if (defined $cd) 
    		{
    			if (defined $cg) 
    			{
     
    				$regles{$cd . '|' . $graph . '|' . $cg} = $repl;
     
    			} 
    			else 
    			{
    				$regles{$cd . '|' . $graph} = $repl;
    			}
    		}
    		else 
    		{
    			if (defined $cg)
    			{
    				$regles{ $graph . '|' . $cg} = $repl;
    			} 
    			else 
    			{
    				$regles{$graph} = $repl;
    			}
    		}
    		undef $cd;
    		undef $cg;
    	}
    }
    #foreach my $graph ( keys %regles ) 
    #{
     # print {$fh_Aran}  $graph, "   ", $regles{$graph},"\n";
    #}
    close $RULES;
     
    my %h = ();
    my $type="";
    my @tab= <IN_Ara>;
    my $size = scalar(@tab);
    chomp @tab; 
    for my $i (0..$size -1) 
    {                   
         my @words = split(/ /, $tab[$i]);
         print "ligne => ".$i."\n";
          $_ =~ s/ +$//g;
          $_ =~ s/^\s+//; 
    	  my $size1 = scalar(@words);
     
    	for my $j (0..$size1 -1)  
    	{
    		#print {$fh_Aran}" $words[$j] \n";  
    		   @car=split (//,$words[$j]);
    		   my $size2 = scalar(@car);
               for my $k (0..$size2 -1)  
    		    {
     
    				if ($car[$k]=~/[ن  ظ ط ض ص ش س ر ز ذ د ت ث ة]/) 
    				{
    				    $type="CS";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";
    				}
    				if ($car[$k]=~/[ڥ پ ڨ]/) 
    				{
    				    $type="C";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";
    				}
    				if ($car[$k]=~/[إ م ه آ ق ف غ ع ج ح خ ب أ ك ء ؤ ئ]/) 
    				{
    				    $type="CL";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";
    				}
     
    				if ($car[$k]=~/\x{064E}/) 
    				{
    				    $type="VC";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";					
    				}
    				if ($car[$k]=~/\x{0650}/) 
    				{
    				   $type="VC";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";				   
    				}
    				if ($car[$k]=~/\x{0652}/) 
    				{
    				   $type="VC";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";				   
    				}
    				if ($car[$k]=~/\x{064F}/) 
    				{
    				   $type="VC";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";			   
    				}
    				if ($car[$k]=~/\x{0651}/) 
    				{
    				    $type="VC";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";					
    				}
    				if ($car[$k]=~/[ى]/)
    				{
    				    $type="VL";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";				
    				}
    				if (($car[$k]=~/[ً]/) and ($car[$k+1]=~/\x{0627}/))
    				{
    				    $type="VC";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";				
                        $type="VL";
    					$k=$k+1;
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";				
    				}
    				if (($car[$k]=~/[ل]/)  and (($car[$k+1])=~/[\x{0651}\x{064F}\x{0652}\x{0650}\x{064E}\x{0652} ً]/)) 
    				{
    				    $type="CS";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";					
    				}
    				if (($car[$k]=~/\x{0627}/) and (($car[$k-1])=~/\x{064E}/) and ( $car[$k+1]!~/[ل]/)) 
    				{
    					$type="VL";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";				
    				}
    				if (($car[$k]=~/\x{0627}/) and (($car[$k-1])=~/\x{064E}/) and ( $car[$k+1]=~/[ل]/) and (($car[$k+2])=~/[\x{0651}\x{064F}\x{0652}\x{0650}\x{064E}\x{0652}]/))
    				{
    					$type="VL";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";			
    				}
    				if (($car[$k]=~/\x{0627}/) and (($car[$k-1])=~/[و]/) and ( $car[$k+1]!~/[ل]/)) 
    				{
    					$type="VL";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";				
    				}
    				if (($car[$k]=~/\x{0627}/) and ( $car[$k+1]=~/[ل]/) and (($car[$k+2])!~/[\x{0651}\x{064F}\x{0652}\x{0650}\x{064E}\x{0652}]/))
    	            {
    	                $type="CL";
    					$h{$words[$j]}{$car[$k].$car[$k+1]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]$car[$k+1]\n";					
    	            }
                    if (($car[$k]=~/[ي]/) and ( $car[$k+1]=~/\x{064E}/))
    	            {
    	               $type="CL";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";			   
    	            }
    				if (($car[$k]=~/[ي]/) and ( $car[$k+1]=~/\x{0650}/))
    	            {
    	               $type="CL";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";				   
    	            }
    				if (($car[$k]=~/[ي]/) and ( $car[$k+1]=~/\x{0652}/))
    	            {
    	               $type="CL";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";			   
    	            }
    				if (($car[$k]=~/[ي]/) and ( $car[$k+1]=~/\x{064F}/))
    	            {
    	               $type="CL";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";				   
    	            }
    				if ($car[$k]=~/[ي]/ and (($car[$k+1])=~/\x{0651}/))
    	            { 
    	                $type="CL";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";				
    	            }	
    				if (($car[$k]=~/\x{0650}/) and (($car[$k+1])=~/[ي]/) and (($car[$k+2])!~/[\x{0651}\x{064F}\x{0652}\x{0650}\x{064E}\x{0652}]/))
    	            { 
    	                $type="VL";
    					$k=$k+1;
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";
    	            }	
                    if (($car[$k]=~/[و]/) and ($car[$k+1]=~/\x{064E}/))
    	            {
    	               $type="CL";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";
    	            }
    				if (($car[$k]=~/[و]/) and ($car[$k+1]=~/\x{0652}/))
    	            {
    	               $type="CL";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";
    	            }
    				if (($car[$k]=~/[و]/) and ( $car[$k+1]=~/\x{0650}/))
    	            {
    	               $type="CL";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";
    	            }
    				if (($car[$k]=~/[و]/) and ( $car[$k+1]=~/\x{064F}/))
    	            {
    	               $type="CL";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";
    	            }
                    if (($car[$k]=~/[و]/) and ( $car[$k+1]=~/\x{0651}/))
    	            {
    	                $type="CL";
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    				    #print {$fh_Aran} "$type $car[$k]\n";
    	            }	 			
     
    				if (($car[$k]=~/\x{064F}/) and (($car[$k+1])=~/[و]/) and (($car[$k+2])!~/[\x{0651}\x{064F}\x{0652}\x{0650}\x{064E}\x{0652}]/))
    	            { 
    	                $type="VL";
    					$k=$k+1;
    					$h{$words[$j]}{$car[$k]}{$type}{$k}++;
    					#print {$fh_Aran} "$type $car[$k]\n";
    	            }	
            	}
     
        }
     
    }
     
        foreach my $words (keys %h )
        {
            foreach my $car ( keys %{$h{$words}} )
    	    {
                foreach my $type ( keys %{$h{$words}{$car}} )
    		    {
                    foreach my $k ( keys %{$h{$words}{$car}{$type}})
    			    {       
    				        #print {$fh_Aran}"'Word', $words \n";  
    						print {$fh_Aran} "$car\n";
                            if (defined $regles{$car})
    					   {
    							print {$fh_Aran} "$regles{graph}\n";
     
    					   }
                    }	
     
                }
            }					
        }

  2. #2
    Membre chevronné Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Par défaut
    Bonjour @bayouta19
    Citation Envoyé par bayouta19 Voir le message
    Bonjour,
    J'ai un programme qui fait la segmentation des mots arabe en caractères et le stockage de ces caractères se fait dans un Hash (h).
    D'après ton code,
    1. $h contient les mots : $h{mot} (J'imagine que chaque mot ne figure qu'une seule fois dans le fichier d'entrée ?)
    2. les caractères d'un mot sont dans $h{mot}{caractère}.

    mais je ne suis pas certain de comprendre les niveaux d'après dans le hash...
    -Le premier problème est l'ordre des caractères n'est pas le même que leur ordre d’apparition dans le mot
    Il y a un autre problème, que tu n'as peut-être pas encore rencontré (à moins que ça ne puisse pas se produire en arabe...) : que se passe-t-il lorsqu'un même caractère apparaît plusieurs fois dans un même mot ?

    Peut-être du coup serait-il mieux adapté d'utiliser une liste pour stocker ces caractères...
    -Le deuxième problème j'aimerais faire la comparaison avec un autre hash (Regles) qui contient pour chaque graphème son remplacement (phonème)
    Voici le code
    ...
    est-ce que tu pourrais donner en attachement un extrait de corpusHash.txt (deux ou trois mots suffiraient) ainsi que de RegleDePhonetisation.xml (là aussi, quelques règles en rapport avec les exemples) ? Ceci pour qu'on puisse discuter en connaissance de cause

  3. #3
    Membre averti
    Femme Profil pro
    Inscrit en
    Janvier 2013
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Femme

    Informations forums :
    Inscription : Janvier 2013
    Messages : 53
    Par défaut
    Bonsoir,
    Oui pour les mots ne se répètent pas dans le fichier d'entrées, et pour les caractère qui se répète dans le mots j'ai ajouter un autre niveau pour résolu le probléme
    Fichiers attachés Fichiers attachés

  4. #4
    Membre chevronné Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Par défaut
    Bonsoir,

    Merci pour les données, et le sérieux avec lequel tu as effectué la sélection +1.

    Pour pouvoir travailler ensemble il va falloir modifier quelque peu ton programme. Par exemple je n'ai pas envie de dupliquer ton arborescence chez moi.
    J'appelle tb19_1.pl ton programme tel que présenté ci-dessus.

    [NOTE : je me suis rendu compte à la toute fin qu'un problème que j'avais avec ton code venait de la présence d'entités HTML en lieu et place de caractères arabes littéraux dans le source... Ca semble dû à la balise CODE. Je pense que c'est corrigé en version 10, donc ne t'étonne pas trop si les résultats des différentes versions intermédiaires ne sont pas ceux auxquels tu t'attendrais, mais je n'ai pas le courage de tout reprendre depuis le début, et en fait ce problème n'a pas d'impact réel sur la restructuration effectuée]

    Vers la version 2

    Apparemment tous tes fichiers résident dans un même répertoire, que tu t'es même donné la peine de définir ($RepBase). On peut s'en servir pour transformer chacune des ligne 14 à 18 sur le modèle suivant, de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my $FichierReglePhonetique ='C:\\Users\\lenovo\\Desktop\\Memoire Mastere\\Script\\Script_final\\Script_Grapheme-phoneme\\tous les scripts\\ScriptV\\RegleDePhonetisation.xml';
    en :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my $FichierReglePhonetique = catfile( $RepBase, 'RegleDePhonetisation.xml' );
    La notation File::Spec->catfile ne présente ici aucun intérêt par rapport à catfile tout simplement, et donc je change également to use File::Spec; en use File::Spec::Functions qw(catfile);Ensuite je change la définition de $RepBase pour pouvoir la modifier en passant un paramètre au script et utiliser la valeur actuelle par défaut. Donc pour toi ça ne changera rien mais ça me simplifie la vie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    my $RepBase = shift @ARGV;
    $RepBase = 'C:\\Users\\lenovo\\Desktop\\Memoire Mastere\\Script\\Script_final\\Script_Grapheme-phoneme\\tous les scripts\\ScriptV'
        unless defined $RepBase;
    Par ailleurs j'ajoute use strict; et use warnings; en tête de programme.
    J'appelle tb19_2.pl le programme ainsi modifié.

    Premier essai:
    Code X : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Taisha:~/tttmp/hashcomp $ perl -c tb19_2.pl .
    "my" variable $graph masks earlier declaration in same scope at tb19_2.pl line 91.
    "my" variable $cg masks earlier declaration in same scope at tb19_2.pl line 91.
    Global symbol "@car" requires explicit package name at tb19_2.pl line 152.
    ...
    Global symbol "@car" requires explicit package name at tb19_2.pl line 324.
    tb19_2.pl had compilation errors.
    Taisha:~/tttmp/hashcomp $

    oups. Certaines variables sont déclarées plusieurs fois, et @car n'est pas déclaré.

    Vers la version 3

    Je corrige tout ça en rajoutant des blocs {} et en déclarant @car. Ca donne tb19_3.pl

    Code x : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Taisha:~/tttmp/hashcomp $ perl -c tb19_3.pl .
    tb19_3.pl syntax OK
    Taisha:~/tttmp/hashcomp $

    Bon on n'a plus d'erreurs évidentes, on va pouvoir commencer à travailler sérieusement

    Pour commencer, on va ajouter les lignes suivantes en fin de programme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    {
        use Data::Dumper;
        my $logfile = "$0.log";
        open my $log , ">", $logfile or die "impossible d'ouvrir $logfile : $! ($^E)";
        print $log Dumper(\%h);
        close $log or die "erreur à la ferleture de $logfile : $! ($^E)";
    }
    ces lignes produisent un dump de $h dans $0.log, où $0 est le nom du script : ainsi
    Code x : Sélectionner tout - Visualiser dans une fenêtre à part
    Taisha:~/tttmp/hashcomp $ perl tb19_3.pl .
    produit maintenant en plus le fichiers tb19_3.pl.log suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    $VAR1 = {
              "\x{64a}\x{650}\x{645}\x{652}\x{634}\x{650}\x{64a}" => {
                                  "\x{652}" => {
                                          'VC' => {
                                                    '3' => 1
                                                  }
                                        },
                                  "\x{650}" => {
                                          'VC' => {
                                                    '1' => 1,
                                                    '5' => 1
                                                  }
                                        }
                                },
              "\x{62a}\x{652}\x{641}\x{64e}\x{636}\x{651}\x{64e}\x{644}\x{652}" => {
                                      "\x{64e}" => {
                                              'VC' => {
                                                        '6' => 1,
                                                        '3' => 1
                                                      }
                                            },
                                      "\x{651}" => {
                                              'VC' => {
                                                        '5' => 1
                                                      }
                                            },
                                      "\x{652}" => {
                                              'VC' => {
                                                        '8' => 1,
                                                        '1' => 1
                                                      }
                                            }
                                    },
              "\x{628}\x{650}\x{627}\x{644}\x{644}\x{647}\x{652}" => {
                                  "\x{652}" => {
                                          'VC' => {
                                                    '6' => 1
                                                  }
                                        },
                                  "\x{650}" => {
                                          'VC' => {
                                                    '1' => 1
                                                  }
                                        }
                                },
              "\x{633}\x{64e}\x{627}\x{639}\x{64e}\x{629}\x{652}" => {
                                  "\x{64e}" => {
                                          'VC' => {
                                                    '4' => 1,
                                                    '1' => 1
                                                  }
                                        },
                                  "\x{652}" => {
                                          'VC' => {
                                                    '6' => 1
                                                  }
                                        },
                                  "\x{627}" => {
                                          'VL' => {
                                                    '2' => 1
                                                  }
                                        }
                                },
              "\x{645}\x{652}\x{639}\x{64e}" => {
                            "\x{64e}" => {
                                    'VC' => {
                                              '3' => 1
                                            }
                                  },
                            "\x{652}" => {
                                    'VC' => {
                                              '1' => 1
                                            }
                                  }
                          },
              "\x{648}\x{64e}\x{642}\x{652}\x{62a}\x{64e}\x{627}\x{634}\x{652}" => {
                                      "\x{64e}" => {
                                              'VC' => {
                                                        '1' => 1,
                                                        '5' => 1
                                                      }
                                            },
                                      "\x{652}" => {
                                              'VC' => {
                                                        '8' => 1,
                                                        '3' => 1
                                                      }
                                            },
                                      "\x{627}" => {
                                              'VL' => {
                                                        '6' => 1
                                                      }
                                            }
                                    },
              "\x{627}\x{644}\x{62a}\x{652}\x{631}\x{64e}\x{627}\x{646}\x{652}" => {
                                      "\x{64e}" => {
                                              'VC' => {
                                                        '5' => 1
                                                      }
                                            },
                                      "\x{652}" => {
                                              'VC' => {
                                                        '8' => 1,
                                                        '3' => 1
                                                      }
                                            },
                                      "\x{627}" => {
                                              'VL' => {
                                                        '6' => 1
                                                      }
                                            }
                                    },
              "\x{62e}\x{64f}\x{648}\x{64a}\x{64e}\x{627}" => {
                                "\x{64e}" => {
                                        'VC' => {
                                                  '4' => 1
                                                }
                                      },
                                "\x{627}" => {
                                        'VL' => {
                                                  '5' => 1
                                                }
                                      },
                                "\x{64f}" => {
                                        'VC' => {
                                                  '1' => 1
                                                }
                                      }
                              }
            };
    Hmmm, ça ne m'a pas l'air très net, il me semble qu'il manque des choses... Mais l'objectif à ce stade est de vérifier que lors des modifications qu'on va faire, on ne change pas le comportement global du programme. Ou bien, que si on le change, on le fait en connaissance de cause. Donc on garde ce fichier sous le coude, il va resservir.

    Vers la version 4

    Ton code souffre d'un abus de copier/coller, et contient encore quelques erreurs à cause de ça. Par exemple, les lignes 49..59 et 61..71 de ton fichier initial sont clairement des copies 37..47. Tu as modifié ce qui devait l'être, mais tu as oublié un détail : le message d'erreur de die, qui fait référence à $FichierBAseException... De plus expérimentés que toi s'y font prendre, mais la leçon en l'occurrence est qu'il faut éviter les copier/coller autant que possible. Une manière de faire est de définir une fonction, et ça marche très bien ici. À partir du code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    open my $EXC, "<", $FichierBAseException or die "Ouverture impossible du fichier $FichierBAseException $! \n";
    while (<$EXC>) 
    {
    	$graph = $1 if /<Grapheme>([^<]+)<\/Grapheme>/;
    	if ( /<Phoneme>([^<]+)<\/Phoneme>/ ) 
    	{
    		$exceptions{$graph} = $1;
     
    	}
    }
    close $EXC;
    on peut définir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    sub lecture_xml {
        my ($filename) = @_;
        my %resultat;
        open my $in, "<", $filename or die "Ouverture impossible du fichier $filename: $! ($^E)\n";
        while (<$in>) {
    	my $graph = $1 if /<Grapheme>([^<]+)<\/Grapheme>/;
    	$resultats{$graph} = $1 if ( /<Phoneme>([^<]+)<\/Phoneme>/ );
        }
        close $in;
        return %resultat;
    }
    et l'utiliser comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    %exceptions = lecture_xml($FichierBAseException);
    %doublepro  = lecture_xml($FichierBAseDouble);
    %etrangers  = lecture_xml($FichierBAseEtrangers);
    Mais le fichier des nombres et celui des règles ne sont pas lus de la même manière ? Qu'à cela ne tienne, on ajoute un paramètre à lecture_xml:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    sub lecture_xml {
        my ($filename, $mode) = @_;
        my %resultat;
        $mode = 'exception' unless defined $mode;
        die "lecture_xml: mode invalide '$mode' (doit être 'exception' ou 'nombre' ou 'regle')"
    	unless $mode eq 'exception' or $mode eq 'nombre' or $mode eq 'regle';
     
        open my $in, "<", $filename or die "Ouverture impossible du fichier $filename: $! ($^E)\n";
        if ($mode eq 'exception') {
    	while (<$in>) {
    	    my $graph = $1 if /<Grapheme>([^<]+)<\/Grapheme>/;
    	    $resultat{$graph} = $1 if ( /<Phoneme>([^<]+)<\/Phoneme>/ );
    	}
        } elsif ($mode eq 'nombre') {
    	while (<$in>) {
    	    my $graph = $1 if /<Grapheme>([^<]+)<\/Grapheme>/;
    	    $resultat{$graph} = $1;
    	}
        } elsif ($mode eq 'regle') {
    	my ($graph, $cd, $cg);
    	while (<$in>) {
    	    $cd = $1 if /<Composant Nom="C-Droit" Utilite="Oui">([^<]+)<\/Composant>/; # $cd sera undef si utilite = non
    	    $graph = $1 if /<Composant Nom="Graph">([^<]+)<\/Composant>/;
    	    $cg = $1 if /<Composant Nom="C-Gauche" Utilite="Oui">([^<]+)<\/Composant>/;
    	    if ( /<Composant Nom="Remplacement">([^<]+)<\/Composant>/ ) {
    		my $repl = $1;
    		# on va créer une clef de hash en concaténant $cd, $cg et $graph (avec séparateur) si ces élements sont définis
    		if (defined $cd) {
    		    if (defined $cg) {
    			$resultat{$cd . '|' . $graph . '|' . $cg} = $repl;
    		    } else {
    			$resultat{$cd . '|' . $graph} = $repl;
    		    }
    		} else {
    		    if (defined $cg) {
    			$resultat{ $graph . '|' . $cg} = $repl;
    		    } else {
    			$resultat{$graph} = $repl;
    		    }
    		}
    	    }
    	    undef $cg;
    	    undef $cd;
    	}
        }
        close $in;
        return %resultat;
    }
    On a ainsi éliminé quelques variables excédentaires ($cd, $cg, $graph) qui n'avaient rien à faire au niveau fichier. J'élimine également les divers $phoneme... et %alif qui ne sont pas utilisés (on les remettra en cas de besoin).

    Ce n'est pas encore la forme que je préfererais pour lecture_xml, mais on va s'arrêter là pour l'instant. Si ça t'intéresse de voir comment l'améliorer encore, dis le moi.

    On l'utilise comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    %exceptions = lecture_xml($FichierBAseException,   'exception');
    %doublepro  = lecture_xml($FichierBAseDouble,      'exception');
    %etrangers  = lecture_xml($FichierBAseEtrangers,   'exception');
    %nombre     = lecture_xml($FichierBAseNombre,      'nombre');
    %regles     = lecture_xml($FichierReglePhonetique, 'regle');
    A ce stade on réalise qu'on n'utilise nulle part ailleurs les noms des fichiers, et donc qu'on peut combiner la déclaration et l'initialisation des hashes et la construction des noms de fichiers:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    my %exceptions = lecture_xml( catfile( $RepBase, 'BaseException.xml'),              'exception');
    my %doublepro  = lecture_xml( catfile( $RepBase, 'BaseException1.xml'),             'exception');
    my %etrangers  = lecture_xml( catfile( $RepBase, 'BaseExceptionMotsEtrangers.xml'), 'exception');
    my %nombre     = lecture_xml( catfile( $RepBase, 'BaseNombre.xml'),                 'nombre');
    my %regles     = lecture_xml( catfile( $RepBase, 'RegleDePhonetisation.xml'),       'regle');
    Ca nous donne tb19_4.pl

    Première tentative d'exécution. Je crée des fichiers BaseException.xml, BaseException1.xml, BaseExceptionMotsEtrangers.xml, BaseNombre.xml (tous vide), dans le répertoire courant qui contient le script, corpusHash.txt et RegleDePhonetisation.xml. Je passe donc comme paramètre '.' (le répertoire courant) pour initialiser correctement $RepBase.

    Code x : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Taisha:~/tttmp/hashcomp $ perl tb19_4.pl .
    Use of uninitialized value $_ in substitution (s///) at tb19_4.pl line 33, <IN_Ara> line 8.
    Use of uninitialized value $_ in substitution (s///) at tb19_4.pl line 34, <IN_Ara> line 8.
    Use of uninitialized value $_ in substitution (s///) at tb19_4.pl line 33, <IN_Ara> line 8.
    Use of uninitialized value $_ in substitution (s///) at tb19_4.pl line 34, <IN_Ara> line 8.
    Use of uninitialized value within @car in pattern match (m//) at tb19_4.pl line 103, <IN_Ara> line 8.
    Use of uninitialized value within @car in pattern match (m//) at tb19_4.pl line 108, <IN_Ara> line 8.
    Use of uninitialized value within @car in pattern match (m//) at tb19_4.pl line 118, <IN_Ara> line 8.
    Use of uninitialized value $_ in substitution (s///) at tb19_4.pl line 33, <IN_Ara> line 8.
    ...
    Use of uninitialized value $_ in substitution (s///) at tb19_4.pl line 34, <IN_Ara> line 8.
    ligne => 0
    ligne => 7
    Taisha:~/tttmp/hashcomp $

    Ouh la, il y a encore du travail On vérifie qu'on n'a pas changé significativement le comportement du programme :
    Code x : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Taisha:~/tttmp/hashcomp $ diff tb19_3.pl.log tb19_4.pl.log 
    Taisha:~/tttmp/hashcomp $
    Aucune différence, on n'a rien cassé à ce stade (en tout cas pas dans la construction de $h).

    Vers la version 5

    les lignes 25 et suivantes de tb19_4.pl se présentent comme suit :

     25   my %h = ();
     26   my $type="";
     27   my @tab= <IN_Ara>;
     28   my $size = scalar(@tab);
     29   chomp @tab;
     30   for my $i (0..$size -1) {
     31       my @words = split(/ /, $tab[$i]);
     32       print "ligne => ".$i."\n";
     33       $_ =~ s/ +$//g;
     34       $_ =~ s/^\s+//;
     35       my $size1 = scalar(@words);
     36   
     37       for my $j (0..$size1 -1) {
     38           #print {$fh_Aran}" $words[$j] \n";
     39           my @car=split (//,$words[$j]);
     40           my $size2 = scalar(@car);
     41           for my $k (0..$size2 -1) {
     42   
     43               if ($car[$k]=~/[ن  ظ ط ض ص ش س ر ز ذ د ت ث ة]/) {
     44                   $type="CS";
     45                   $h{$words[$j]}{$car[$k]}{$type}{$k}++;
     46                   #print {$fh_Aran} "$type $car[$k]\n";
     47               }
    Tout ça m'a l'air bien compliqué et répétitif... Tu n'as pas besoin de $size, tu ne t'en sert qu'en ligne 30 , et tu peux utiliser $#tab qui est égal à $size-1. Mais de toute façon @tab ne te sert pas à grand chose... Les lignes 33 et 34 cherchent apparemment à éliminer les espaces en début et fin de ligne mais malheureusement $_ n'est pas assigné à la ligne... De la même manière $j et $size1 ne sont pas utilisés ensuite. Admettons pour l'instant que $k puisse servir (c'est la position du caractère dans le mot). On peut simplifier les boucle comme suit :

     24   $| = 1;
     25   binmode *STDOUT, ':encoding(UTF-8)';
     26   my %h = ();
     27   my $type="";
     28   while (<IN_Ara>) {
     29       chomp;
     30       print "Ligne => $. [$_]\n";
     31       my @words = split;
     32       for my $word (@words) {
     33           my @car = split //, $word;
     34           my $thisword;
     35           for my $k (0 .. $#car) {
     36   
     37               if ($car[$k]=~/[ن  ظ ط ض ص ش س ر ز ذ د ت ث ة]/) {
     38                   $type="CS";
     39                   $thisword->{$car[$k]}{$type}{$k}++;
     40                   #print {$fh_Aran} "$type $car[$k]\n";
     41               }
    ...               ...
    180           }
    181           $h{$_} = $thisword;
    182       }
    183   }
    Quelques points à noter :
    • en ligne 24, on force l'autoflush sur STDOUT, ce qui permet d'entrelacer correctement les print sur STDOUT et STDERR (e.g. les warnings)
    • en ligne 25, on passe STDOUT en encoding UTF-8, ce qui permet d'afficher les caractères arabes dans les impressions de contrôle.
    • en ligne 28, on lit maintenant le fichier ligne par ligne
    • en ligne 30, $. est le numéro de la ligne courante. Par rapport à la version initiale, il démarre à 1 au lieu de 0, il y a donc un décalage. J'ai ajouté l'impression de la ligne courante entre crochets.
    • en ligne 31, le split utilise l'option par défaut qui ignore les espaces initiaux et finaux, ce qui fait que les lignes 33 et 34 de tb19_4.pl n'ont plus de raison d'être
    • note l'utilisation de $thisword, qui va servir à capturer l'info pour le mot courant. On remplace donc partout $h{$words[$j]} par $thisword->. On le stocke dans ${h} en ligne 181.


    Ca nous donne tb19_5.pl :

    Code x : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Taisha:~/tttmp/hashcomp $ perl tb19_5.pl .
    Ligne => 1 [تْفَضَّلْ]
    Ligne => 2 [خُويَا]
    Use of uninitialized value within @car in pattern match (m//) at tb19_5.pl line 97, <IN_Ara> line 2.
    Use of uninitialized value within @car in pattern match (m//) at tb19_5.pl line 102, <IN_Ara> line 2.
    Use of uninitialized value within @car in pattern match (m//) at tb19_5.pl line 112, <IN_Ara> line 2.
    Ligne => 3 [مْعَ]
    Ligne => 4 [وَقْتَاشْ]
    Ligne => 5 [بِاللهْ]
    Ligne => 6 [التْرَانْ]
    Ligne => 7 [يِمْشِي]
    Ligne => 8 [سَاعَةْ]
    Taisha:~/tttmp/hashcomp $ diff tb19_3.pl.log tb19_5.pl.log 
    Taisha:~/tttmp/hashcomp $

    On n'a toujours apparemment rien cassé. On voit mieux maintenant l'origine des warnings. Mais ce n'est pas tout à fait assez précis. Pour quelle valeur de $k a-t-on des problèmes ? Pour le savoir, on change la ligne 36 comme suit pour enrichir le message :
     35           for my $k (0 .. $#car) {
     36               $SIG{__WARN__} = sub { print "caractère $k sur $#car, ", @_ };
     37               if ($car[$k]=~/[ن  ظ ط ض ص ش س ر ز ذ د ت ث ة]/) {
    et maintenant
    Code x : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Taisha:~/tttmp/hashcomp $ perl tb19_5.pl .
    Ligne => 1 [تْفَضَّلْ]
    Ligne => 2 [خُويَا]
    $k = 5, $#car = 5, Use of uninitialized value within @car in pattern match (m//) at tb19_5.pl line 97, <IN_Ara> line 2.
    $k = 5, $#car = 5, Use of uninitialized value within @car in pattern match (m//) at tb19_5.pl line 102, <IN_Ara> line 2.
    $k = 5, $#car = 5, Use of uninitialized value within @car in pattern match (m//) at tb19_5.pl line 112, <IN_Ara> line 2.
    Ligne => 3 [مْعَ]
    Ligne => 4 [وَقْتَاشْ]
    Ligne => 5 [بِاللهْ]
    Ligne => 6 [التْرَانْ]
    Ligne => 7 [يِمْشِي]
    Ligne => 8 [سَاعَةْ]
    Taisha:~/tttmp/hashcomp $
    voyons voir les lignes en question (97, 102, 112) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
               if (($car[$k]=~/\x{0627}/) and (($car[$k-1])=~/\x{064E}/) and ( $car[$k+1]!~/[ل]/)) {
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
               if (($car[$k]=~/\x{0627}/) and (($car[$k-1])=~/\x{064E}/) and ( $car[$k+1]=~/[ل]/) and (($car[$k+2])=~/[\x{0651}\x{064F}\x{0652}\x{0650}\x{064E}\x{0652}]/)) {
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
               if (($car[$k]=~/\x{0627}/) and ( $car[$k+1]=~/[ل]/) and (($car[$k+2])!~/[\x{0651}\x{064F}\x{0652}\x{0650}\x{064E}\x{0652}]/)) {
    Bon, c'est clair : on a cherché à accéder à $car[$k+1] et ce caractère n'existe pas car on est déjà en fin de chaîne.

    Vers la version 6

    Il y a une subtilité ici. Qu'est-ce qui se passe lorsqu'on tente d'accéder au $k+1 eme élément d'un tableau qui n'en comporte que $k ? Eh bien cet élément est autovivifié, autrement dit le tableau est agrandi d'un élément, dont la valeur est undef. C'est utile dans certaines circonstances. Ça n'a peut-être pas de conséquences nuisibles ici, je n'en sais rien, mais ce n'est pas très propre. On pourrait empêcher cette autovivification de diverses manières mais il y a un autre point à noter avant.

    Comment se fait-il qu'on n'ait pas eu de warnings analogues lors de l'accès à $car[$k-1] lorsque $k vaut 0 ? Eh bien il se trouve que Perl permet d'accéder à un tableau à partir de sa fin : $car[-1] désigne le dernier élément du tableau, $car[-2] l'avant dernier, etc... Du coup c'est parfaitement légitime et Perl ne donne pas de warning dans ce cas. Mais on voit bien que ça pourraît être un bug dans le code ci-dessus (en fait, il est possible que ces circonstances ne puissent jamais se produire sur des mots arabes mais pour ma tranquillité d'esprit je préfère ne pas prendre le risque ).

    La bonne méthode pour traiter ces dépassements pour les index est donc de tester explicitement si $k est bien tel que $car[$k-1], $car[$k+1], $car[k+2], etc existent lorsqu'on cherche à les utiliser. On change donc la ligne 97 en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
               if (($car[$k]=~/\x{0627}/) and (($k > 0) and ($car[$k-1])=~/\x{064E}/) and ($k < $#car) and ( $car[$k+1]!~/[ل]/)) {
    et on fait de même pour celles utilisant $car[$k-1], $car[$k+1], $car[k+2], etc.

    Ce qui nous amène à tp19_6.pl.
    Code x : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Taisha:~/tttmp/hashcomp $ perl tb19_6.pl .
    Ligne => 1 [تْفَضَّلْ]
    Ligne => 2 [خُويَا]
    Ligne => 3 [مْعَ]
    Ligne => 4 [وَقْتَاشْ]
    Ligne => 5 [بِاللهْ]
    Ligne => 6 [التْرَانْ]
    Ligne => 7 [يِمْشِي]
    Ligne => 8 [سَاعَةْ]
    Taisha:~/tttmp/hashcomp $
    Tiens tiens ! Cette fois le diff n'est plus vide
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Taisha:~/tttmp/hashcomp $ diff tb19_3.pl.log tb19_6.pl.log 
    119,123d118
    <                             "\x{627}" => {
    <                                     'VL' => {
    <                                               '5' => 1
    <                                             }
    <                                   },
    Taisha:~/tttmp/hashcomp $
    Il semble que les dernières modifications aient eu un effet... Espérons qu'il soit positif . Le signe < en tête de ligne indique que le contenu présenté était dans tb19_3.pl.log et pas dans tb19_6.pl.log. Mais comment savoir quelle règle a été déclenchée dans les versions antérieures pour ajouter ce résultat ? Il y a fort à parier que ce soit l'une des lignes 97, 102 ou 112 de t19_5.pl, celles qui produisaient les warnings...

    Regardons la ligne 97 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
                if (($car[$k]=~/\x{0627}/) and (($car[$k-1])=~/\x{064E}/) and ( $car[$k+1]!~/[ل]/)) {
    Pas la peine d'aller plus loin, c'est la bonne. On voit qu'elle s'est déclenchée pour une mauvaise raison : ici $car[5] est bien \x{0627}, $car[4] est bien \x{064E}, mais il n'y a pas de 7eme caractère, $car[6] est undef, et le dernier test réussit (les négations de match sont dangereuses lorsqu'un des éléments est undef...).

    En tous cas, on n'a donc pas perdu notre temps

    Vers la version 7

    Il y a un truc qui me démange depuis le début, c'est la répétition de code dans les tests de la boucle interne. Les blocs des tests sont presque tous identiques, au type près. C'est une circonstance qui implore l'utilisation d'une fonction.

    Ici ce qu'on va faire dans un premier temps, c'est utiliser une fonction anonyme locale à la boucle : on remplace
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
            for my $k (0 .. $#car) {
                $SIG{__WARN__} = sub { print "caractère $k sur $#car, \$car[$k] = $car[$k]", @_ };
                if ($car[$k] =~ /[ن  ظ ط ض ص ش س ر ز ذ د ت ث ة]/) {
                    $type="CS";
                    $thisword->{$car[$k]}{$type}{$k}++;
                    #print {$fh_Aran} "$type $car[$k]\n";
                }
                if ($car[$k] =~ /[ڥ پ ڨ]/) {
                    $type="C";
                    $thisword->{$car[$k]}{$type}{$k}++;
                    #print {$fh_Aran} "$type $car[$k]\n";
                }
                if ($car[$k] =~ /[إ م ه آ ق ف غ ع ج ح خ ب أ ك ء ؤ ئ]/) {
                    $type="CL";
                    $thisword->{$car[$k]}{$type}{$k}++;
                    #print {$fh_Aran} "$type $car[$k]\n";
                }
                ...
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
            for my $k (0 .. $#car) {
                $SIG{__WARN__} = sub { print "caractère $k sur $#car, \$car[$k] = $car[$k]", @_ };
                my $set_type = sub {
                    my ($k, $str, $type) = @_;
                    $thisword->{$str}{$type}{$k}++;
                    #print {$fh_Aran} "$type $str\n";
                };
                if ($car[$k] =~ /[ن  ظ ط ض ص ش س ر ز ذ د ت ث ة]/) {
                    $set_type->($k, $car[$k], "CS");
                }
                if ($car[$k] =~ /[ڥ پ ڨ]/) {
                    $set_type->($k, $car[$k], "C");
                }
                if ($car[$k] =~ /[إ م ه آ ق ف غ ع ج ح خ ب أ ك ء ؤ ئ]/) {
                    $set_type->($k, $car[$k], "CL");
                }
                ...
    plusieurs points à noter:
    • notre fonction anonyme est liée au scalaire $set_type
    • on y accède via $set_type->(...)
    • il n'est pas nécessaire de déclarer $thisword ou @car à l'intérieur de la sub, car elle voit les variables déclarées dans son environnement.
    • le fait de passer $k en paramètre permet de transformer plus bas
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
                  if (($car[$k] =~ /[ً]/) and (($k < $#car) and ($car[$k+1] =~ /\x{0627}/))) {
                      $type="VC";
                      $thisword->{$car[$k]}{$type}{$k}++;
                      #print {$fh_Aran} "$type $car[$k]\n";
                      $type="VL";
                      $k=$k+1;
                      $thisword->{$car[$k]}{$type}{$k}++;
                      #print {$fh_Aran} "$type $car[$k]\n";
                  }
      en
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
                  if (($car[$k] =~ /[ً]/) and (($k < $#car) and ($car[$k+1] =~ /\x{0627}/))) {
                      $set_type->($k, "VC");
                      $set_type->($k+1, "VL");
                  }
      ce qui devrait éviter un bug potentiel (si jamais ce test passe, c'est avec un index incrémenté qu'on attaque les tests suivants et je ne crois pas que ce soit désiré...)
    • le fait de passer $str en paramètre permet de traiter le cas particulier
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
                  if (($car[$k] =~ /\x{0627}/) and (($k < $#car) and ($car[$k+1] =~ /[ل]/)) and (($k < $#car-1) and ($car[$k+2])!~/[\x{0651}\x{064F}\x{0652}\x{0650}\x{064E}\x{0652}]/)) {
                      $type="CL";
                      $thisword->{$car[$k].$car[$k+1]}{$type}{$k}++;
                      #print {$fh_Aran} "$type $car[$k]$car[$k+1]\n";
                  }
      par
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
                  if (($car[$k] =~ /\x{0627}/) and (($k < $#car) and ($car[$k+1] =~ /[ل]/)) and (($k < $#car-1) and ($car[$k+2])!~/[\x{0651}\x{064F}\x{0652}\x{0650}\x{064E}\x{0652}]/)) {
                      $set_type->($k, $car[$k].$car[$k+1], "CL");
                  }


    Après application de ces modifications, on en est à tb19_7.pl. Vérification :
    Code x : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Taisha:~/tttmp/hashcomp $ perl tb19_7.pl .
    Ligne => 1 [تْفَضَّلْ]
    Ligne => 2 [خُويَا]
    Ligne => 3 [مْعَ]
    Ligne => 4 [وَقْتَاشْ]
    Ligne => 5 [بِاللهْ]
    Ligne => 6 [التْرَانْ]
    Ligne => 7 [يِمْشِي]
    Ligne => 8 [سَاعَةْ]
    Taisha:~/tttmp/hashcomp $ diff tb19_6.pl.log  tb19_7.pl.log
    Taisha:~/tttmp/hashcomp $

    Même comportement que la version précédente, ouf. Maintenant le code est plus facile à modifier : par exemple, si on voulait dé-commenter les #print {$fh_Aran} "$type $car[$k]\n";, on n'aurait plus qu'à le faire en un seul endroit

    Vers la version 8

    Mais en fait je n'aime pas trop ces séquences de tests similaires. Pour le coup on va tenter une restructuration un peu musclée...

    Un test comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
                if ($car[$k] =~ /[ڥ پ ڨ]/) {
                    $set_type->($k, $car[$k], "C");
                }
    pourraît être reformulé comme suit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
                if ($condition->($k)) {
                    $action->($k)
                }
    avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $condition = sub { my ($k) = @_; $car[$k] =~ /[ڥ پ ڨ]/ };
    $action = sub { my ($k) = @_; $set_type->($k, $car[$k], "C") };
    et si on place ces deux sub dans un hash
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $test = {
        condition => sub { my ($k) = @_; $car[$k] =~ /[ڥ پ ڨ]/ },
        action    => sub { my ($k) = @_; $set_type->($k, $car[$k], "C") },
    };
    alors on peut effectuer le test comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
                if ($test->{condition}->($k)) {
                    $test->{action}->($k)
                }
    Imaginons qu'on ait rangé tous les tests dans une liste de (références à des) hashes de ce type. Alors on pourrait les exécuter comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    foreach my $test ( @liste_des_tests ) {
        if ($test->{condition}->()) {
            $test->{action}->()
        }
    }
    Ce hash est bien pratique, on peut y ajouter d'autres informations, comme un identifiant pour chaque règle, ou un commentaire qu'on pourra utiliser ultérieurement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $test = {
        id        => "R01",
        comment   => ...,
        condition => sub { ... },
        action    => sub { ... },
    };
    Essayons voir, dans tb19_8.pl, qui ressemble à ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    my $type="";
    while (<IN_Ara>) {
        chomp;
        print "Ligne => $. [$_]\n";
        my @words = split;
        for my $word (@words) {
            my @car = split //, $word;
            my $thisword;
            for my $k (0 .. $#car) {
                $SIG{__WARN__} = sub { print "caractère $k sur $#car, \$car[$k] = $car[$k]", @_ };
                my $set_type = sub {
                    my ($k, $str, $type) = @_;
                    $thisword->{$str}{$type}{$k}++;
                    #print {$fh_Aran} "$type $str\n";
                };
                my @liste_des_tests
                  = (
                     {
                      id        => q{R01},
                      condition => sub { my ($k) = @_; $car[$k] =~ /[ن  ظ ط ض ص ش س ر ز ذ د ت ث ة]/ },
                      action    => sub { my ($k) = @_; $set_type->($k, $car[$k], "CS") },
                     },
                     ...
                     {
                      id        => q{R10},
                      condition => sub { my ($k) = @_; ($car[$k] =~ /[ً]/) and (($k < $#car) and ($car[$k+1] =~ /\x{0627}/)) },
                      action    => sub { my ($k) = @_; $set_type->($k, $car[$k], "VC"); $set_type->($k+1, $car[$k+1], "VL") },
                     },
                     ...
                     {
                      id        => q{R15},
                      condition => sub { my ($k) = @_; ($car[$k] =~ /\x{0627}/) and (($k < $#car) and ($car[$k+1] =~ /[ل]/)) and (($k < $#car-1) and ($car[$k+2])!~/[\x{0651}\x{064F}\x{0652}\x{0650}\x{064E}\x{0652}]/) },
                      action    => sub { my ($k) = @_; $set_type->($k, $car[$k].$car[$k+1], "CL") },
                     },
    		 ...
    		 {
                      id        => q{R27},
                      condition => sub { my ($k) = @_; ($car[$k] =~ /\x{064F}/) and (($k < $#car) and ($car[$k+1] =~ /[& #1608;]/)) and (($k < $#car-1) and ($car[$k+2])!~/[\x{0651}\x{064F}\x{0652}\x{0650}\x{064E}\x{0652}]/) },
                      action    => sub { my ($k) = @_; $set_type->($k+1, $car[$k+1], "VL") },
                     },
                    );
                for my $test (@liste_des_tests) {
                    if ($test->{condition}->($k)) {
                        $test->{action}->($k);
                    }
                }
            }
            $h{$word} = $thisword;
        }
    }
    Ça a toujours l'air de fonctionner comme avant...

    Code x : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Taisha:~/tttmp/hashcomp $ perl tb19_8.pl .
    Ligne => 1 [تْفَضَّلْ]
    Ligne => 2 [خُويَا]
    Ligne => 3 [مْعَ]
    Ligne => 4 [وَقْتَاشْ]
    Ligne => 5 [بِاللهْ]
    Ligne => 6 [التْرَانْ]
    Ligne => 7 [يِمْشِي]
    Ligne => 8 [سَاعَةْ]
    Taisha:~/tttmp/hashcomp $ diff tb19_6.pl.log tb19_8.pl.log  
    Taisha:~/tttmp/hashcomp $

    Vers la version 9

    Par contre il y a un truc qui ne va pas tout à fait : on redéfinit @liste_des_tests à chaque passage dans la boucle interne... Ce n'est vraiment pas efficace. Il faudrait déporter sa définition en dehors de la boucle externe while (<IN_Ara>) { ... }. C'est possible, à condition de déplacer au même niveau les déclarations de @car et $thisword (sans oublier d'initialiser ce dernier avant de rentrer dans la boucle interne). On en profite pour déplacer également set_type. Pour ne pas polluer l'espace de nommage global, on va introduire un bloc. Oh, et entre parenthèses, la déclaration de $type au niveau global ne sert plus à rien, on la supprime.

    Ce qui nous donne tb19_9.pl, qui ressemble à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    $| = 1;
    binmode *STDOUT, ':encoding(UTF-8)';
    my %h = ();
    {
        my @car;
        my $thisword;
        my $set_type = sub { ... };
        my @liste_des_tests = ( ... );
        while (<IN_Ara>) {
            chomp;
            print "Ligne => $. [$_]\n";
            my @words = split;
            for my $word (@words) {
                @car = split //, $word;
                $thisword = undef;
                for my $k (0 .. $#car) {
                    $SIG{__WARN__} = sub { print "caractère $k sur $#car, \$car[$k] = $car[$k]", @_ };
                    for my $test (@liste_des_tests) {
                        if ($test->{condition}->($k)) {
                            $test->{action}->($k);
                        }
                    }
                }
                $h{$word} = $thisword;
            }
        }
    }
    Avec un avantage : on peut maintenant ajouter sans peine des impressions de trace ou de debug. On définit une variable globale $Debug, passée en paramètre comme $RepBase :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    my $RepBase = shift @ARGV;
    $RepBase = 'C:\\Users\\lenovo\\Desktop\\Memoire Mastere\\Script\\Script_final\\Script_Grapheme-phoneme\\tous les scripts\\ScriptV'
        unless defined $RepBase;
    my $Debug   = shift @ARGV;
    , et maintenant $Debug aura la valeur du second paramètre passé au programme (undef, donc faux, s'il n'y en a pas). On définit quelque part
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    sub slash_x {
        my ($car) = @_;
        join q{}, map { sprintf("\\x{%04x}", ord($_)) } map { split //, $_ } @_
    }
    , on déclare $regle_id (au même niveau que @car), on ajoute une ligne dans la boucle sur @liste_des_tests
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
                    for my $test (@liste_des_tests) {
                        if ($test->{condition}->($k)) {
                            $id_regle = $test->{id};
                            $test->{action}->($k);
                        }
                    }
    , on ajoute une ligne à set_type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        my $set_type = sub {
                    my ($k, $str, $type) = @_;
                    print "    \$k = $k, \$str = $str ", slash_x($str), " ==> type $type (règle = $regle_id)\n" if $Debug;
                    $thisword->{$str}{$type}{$k}++;
                    #print {$fh_Aran} "$type $str\n";
                };
    , et une ligne supplémentaire dans la boucle sur @words :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            for my $word (@words) {
                @car = split //, $word;
                print "  Mot $word ", slash_x($word), "\n" if $Debug;
                $thisword = undef;
    À l'exécution, avec un second paramètre d'appel à 0 (donc faux, on aurait aussi bien pu l'omettre), le comportement est inchangé
    Code x : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Taisha:~/tttmp/hashcomp $ perl tb19_9.pl . 0
    Ligne => 1 [تْفَضَّلْ]
    Ligne => 2 [خُويَا]
    Ligne => 3 [مْعَ]
    Ligne => 4 [وَقْتَاشْ]
    Ligne => 5 [بِاللهْ]
    Ligne => 6 [التْرَانْ]
    Ligne => 7 [يِمْشِي]
    Ligne => 8 [سَاعَةْ]
    Taisha:~/tttmp/hashcomp $ diff tb19_6.pl.log tb19_9.pl.log  
    Taisha:~/tttmp/hashcomp $
    Par contre si on passe comme second paramètre quelque chose qui s'évalue à vrai et qui active les traces, on obtient
    Code x : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    Taisha:~/tttmp/hashcomp $ perl tb19_9.pl . 1
    Ligne => 1 [تْفَضَّلْ]
      Mot تْفَضَّلْ \x{062a}\x{0652}\x{0641}\x{064e}\x{0636}\x{0651}\x{064e}\x{0644}\x{0652}
        $k = 1, $car[1] = ْ \x{0652} ==> type VC (règle = R06)
        $k = 3, $car[3] = َ \x{064e} ==> type VC (règle = R04)
        $k = 5, $car[5] = ّ \x{0651} ==> type VC (règle = R08)
        $k = 6, $car[6] = َ \x{064e} ==> type VC (règle = R04)
        $k = 8, $car[8] = ْ \x{0652} ==> type VC (règle = R06)
    Ligne => 2 [خُويَا]
      Mot خُويَا \x{062e}\x{064f}\x{0648}\x{064a}\x{064e}\x{0627}
        $k = 1, $car[1] = ُ \x{064f} ==> type VC (règle = R07)
        $k = 4, $car[4] = َ \x{064e} ==> type VC (règle = R04)
    Ligne => 3 [مْعَ]
      Mot مْعَ \x{0645}\x{0652}\x{0639}\x{064e}
        $k = 1, $car[1] = ْ \x{0652} ==> type VC (règle = R06)
        $k = 3, $car[3] = َ \x{064e} ==> type VC (règle = R04)
    Ligne => 4 [وَقْتَاشْ]
      Mot وَقْتَاشْ \x{0648}\x{064e}\x{0642}\x{0652}\x{062a}\x{064e}\x{0627}\x{0634}\x{0652}
        $k = 1, $car[1] = َ \x{064e} ==> type VC (règle = R04)
        $k = 3, $car[3] = ْ \x{0652} ==> type VC (règle = R06)
        $k = 5, $car[5] = َ \x{064e} ==> type VC (règle = R04)
        $k = 6, $car[6] = ا \x{0627} ==> type VL (règle = R12)
        $k = 8, $car[8] = ْ \x{0652} ==> type VC (règle = R06)
    Ligne => 5 [بِاللهْ]
      Mot بِاللهْ \x{0628}\x{0650}\x{0627}\x{0644}\x{0644}\x{0647}\x{0652}
        $k = 1, $car[1] = ِ \x{0650} ==> type VC (règle = R05)
        $k = 6, $car[6] = ْ \x{0652} ==> type VC (règle = R06)
    Ligne => 6 [التْرَانْ]
      Mot التْرَانْ \x{0627}\x{0644}\x{062a}\x{0652}\x{0631}\x{064e}\x{0627}\x{0646}\x{0652}
        $k = 3, $car[3] = ْ \x{0652} ==> type VC (règle = R06)
        $k = 5, $car[5] = َ \x{064e} ==> type VC (règle = R04)
        $k = 6, $car[6] = ا \x{0627} ==> type VL (règle = R12)
        $k = 8, $car[8] = ْ \x{0652} ==> type VC (règle = R06)
    Ligne => 7 [يِمْشِي]
      Mot يِمْشِي \x{064a}\x{0650}\x{0645}\x{0652}\x{0634}\x{0650}\x{064a}
        $k = 1, $car[1] = ِ \x{0650} ==> type VC (règle = R05)
        $k = 3, $car[3] = ْ \x{0652} ==> type VC (règle = R06)
        $k = 5, $car[5] = ِ \x{0650} ==> type VC (règle = R05)
    Ligne => 8 [سَاعَةْ]
      Mot سَاعَةْ \x{0633}\x{064e}\x{0627}\x{0639}\x{064e}\x{0629}\x{0652}
        $k = 1, $car[1] = َ \x{064e} ==> type VC (règle = R04)
        $k = 2, $car[2] = ا \x{0627} ==> type VL (règle = R12)
        $k = 4, $car[4] = َ \x{064e} ==> type VC (règle = R04)
        $k = 6, $car[6] = ْ \x{0652} ==> type VC (règle = R06)
    Taisha:~/tttmp/hashcomp $

    Il me semble que ça permet d'y voir nettement plus clair

    Notre restructuration "musclée", qui a consisté à transformer la séquence de tests en une boucle de parcours d'une liste, ouvre clairement des possibilités très intéressantes. Si on veut modifier le traitement effectué, il nous suffit maintenant d'intervenir une seule fois dans set_type, et non plus à l'intérieur de chaque bloc des tests initiaux. Par ailleurs on peut gérer les cas particuliers en modifiant individuellement la condition ou l'action de chaque test, donc on n'a pas pour autant perdu en flexibilité.

    Et on n'a toujours rien cassé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Taisha:~/tttmp/hashcomp $ diff tb19_6.pl.log tb19_9.pl.log  
    Taisha:~/tttmp/hashcomp $
    Vers la version 10

    Il reste à corriger un point important, à savoir l'utilisation d'entités HTML comme ن dans le source... Je viens de comprendre d'où ils proviennent. J'ai récupéré le source par copier/coller de celui publié dans ton message initial. Apparemment, la balise CODE (qui dans ce forum est équivalente à CODE=perl) transforme les caractère utf8 un peu exotiques en les remplaçant par l'entité HTML correspondante. C'est casse pieds... Ce n'est pas le cas pour CODE=x, que j'utilisais pour les exemples d'exécution, et c'est pour celà qu'on les voit dans ce cas...

    Quoi qu'il en soit, il faut les corriger car Perl ne les comprends certainement pas sous cette forme. Heureusement, un uniligne perl suffit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Taisha:~/tttmp/hashcomp $ perl -pE 's/\s*(&#(\d+);)\s*/sprintf("\\x{%04x}",$2)/ge' tb19_9.pl > tb19_10.pl
    Taisha:~/tttmp/hashcomp $
    qui transforme le code comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Taisha:~/tttmp/hashcomp $ diff tb19_9.pl tb19_10.pl 
    42c42
    <           condition => sub { my ($k) = @_; $car[$k] =~ /[ن  ظ ط ض ص ش س ر ز ذ د ت ث ة]/ },
    ---
    >           condition => sub { my ($k) = @_; $car[$k] =~ /[\x{0646}\x{0638}\x{0637}\x{0636}\x{0635}\x{0634}\x{0633}\x{0631}\x{0632}\x{0630}\x{062f}\x{062a}\x{062b}\x{0629}]/ },
    ...
    On peut de même transformer à nouveau tous les caractères échappés (par exemple \x{0646}) en caractère arabe (ن) avec l'uniligne suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Taisha:~/tttmp/hashcomp $ perl -pE 's/\\x{([[:xdigit:]]+)}/chr(hex($1))/ge' tb19_10.pl > tb19_10a.pl
    Et en faisant attention à bien utiliser CODE=x on voit qu'on obtient
    Code x : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Taisha:~/tttmp/hashcomp $ diff tb19_10.pl tb19_10a.pl
    42c42
    <           condition => sub { my ($k) = @_; $car[$k] =~ /[\x{0646}\x{0638}\x{0637}\x{0636}\x{0635}\x{0634}\x{0633}\x{0631}\x{0632}\x{0630}\x{062f}\x{062a}\x{062b}\x{0629}]/ },
    ---
    >           condition => sub { my ($k) = @_; $car[$k] =~ /[نظطضصشسرزذدتثة]/ },
    47c47
    <           condition => sub { my ($k) = @_; $car[$k] =~ /[\x{06a5}\x{067e}\x{06a8}]/ },
    ---
    >           condition => sub { my ($k) = @_; $car[$k] =~ /[ڥپڨ]/ },
    52c52
    <           condition => sub { my ($k) = @_; $car[$k] =~ /[\x{0625}\x{0645}\x{0647}\x{0622}\x{0642}\x{0641}\x{063a}\x{0639}\x{062c}\x{062d}\x{062e}\x{0628}\x{0623}\x{0643}\x{0621}\x{0624}\x{0626}]/ },
    ---
    >           condition => sub { my ($k) = @_; $car[$k] =~ /[إمهآقفغعجحخبأكءؤئ]/ },
    ...
    et si ce format est plus confortable pour toi n'hésite pas à le faire (et me le dire). Pour l'instant je reste sur la version 10.

    Normalement on devrait avoir changé le comportement à ce stade car de nouvelles règles devraient s'activer maintenant. Effectivement :
    Code x : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    Taisha:~/tttmp/hashcomp $ perl tb19_10.pl . 1
    Ligne => 1 [تْفَضَّلْ]
      Mot تْفَضَّلْ \x{062a}\x{0652}\x{0641}\x{064e}\x{0636}\x{0651}\x{064e}\x{0644}\x{0652}
        $k = 0, $str = ت \x{062a} ==> type CS (règle = R01)
        $k = 1, $str = ْ \x{0652} ==> type VC (règle = R06)
        $k = 2, $str = ف \x{0641} ==> type CL (règle = R03)
        $k = 3, $str = َ \x{064e} ==> type VC (règle = R04)
        $k = 4, $str = ض \x{0636} ==> type CS (règle = R01)
        $k = 5, $str = ّ \x{0651} ==> type VC (règle = R08)
        $k = 6, $str = َ \x{064e} ==> type VC (règle = R04)
        $k = 7, $str = ل \x{0644} ==> type CS (règle = R11)
        $k = 8, $str = ْ \x{0652} ==> type VC (règle = R06)
    Ligne => 2 [خُويَا]
      Mot خُويَا \x{062e}\x{064f}\x{0648}\x{064a}\x{064e}\x{0627}
        $k = 0, $str = خ \x{062e} ==> type CL (règle = R03)
        $k = 1, $str = ُ \x{064f} ==> type VC (règle = R07)
        $k = 3, $str = ي \x{064a} ==> type CL (règle = R16)
        $k = 4, $str = َ \x{064e} ==> type VC (règle = R04)
    Ligne => 3 [مْعَ]
      Mot مْعَ \x{0645}\x{0652}\x{0639}\x{064e}
        $k = 0, $str = م \x{0645} ==> type CL (règle = R03)
        $k = 1, $str = ْ \x{0652} ==> type VC (règle = R06)
        $k = 2, $str = ع \x{0639} ==> type CL (règle = R03)
        $k = 3, $str = َ \x{064e} ==> type VC (règle = R04)
    Ligne => 4 [وَقْتَاشْ]
      Mot وَقْتَاشْ \x{0648}\x{064e}\x{0642}\x{0652}\x{062a}\x{064e}\x{0627}\x{0634}\x{0652}
        $k = 0, $str = و \x{0648} ==> type CL (règle = R22)
        $k = 1, $str = َ \x{064e} ==> type VC (règle = R04)
        $k = 2, $str = ق \x{0642} ==> type CL (règle = R03)
        $k = 3, $str = ْ \x{0652} ==> type VC (règle = R06)
        $k = 4, $str = ت \x{062a} ==> type CS (règle = R01)
        $k = 5, $str = َ \x{064e} ==> type VC (règle = R04)
        $k = 6, $str = ا \x{0627} ==> type VL (règle = R12)
        $k = 7, $str = ش \x{0634} ==> type CS (règle = R01)
        $k = 8, $str = ْ \x{0652} ==> type VC (règle = R06)
    Ligne => 5 [بِاللهْ]
      Mot بِاللهْ \x{0628}\x{0650}\x{0627}\x{0644}\x{0644}\x{0647}\x{0652}
        $k = 0, $str = ب \x{0628} ==> type CL (règle = R03)
        $k = 1, $str = ِ \x{0650} ==> type VC (règle = R05)
        $k = 2, $str = ال \x{0627}\x{0644} ==> type CL (règle = R15)
        $k = 5, $str = ه \x{0647} ==> type CL (règle = R03)
        $k = 6, $str = ْ \x{0652} ==> type VC (règle = R06)
    Ligne => 6 [التْرَانْ]
      Mot التْرَانْ \x{0627}\x{0644}\x{062a}\x{0652}\x{0631}\x{064e}\x{0627}\x{0646}\x{0652}
        $k = 0, $str = ال \x{0627}\x{0644} ==> type CL (règle = R15)
        $k = 2, $str = ت \x{062a} ==> type CS (règle = R01)
        $k = 3, $str = ْ \x{0652} ==> type VC (règle = R06)
        $k = 4, $str = ر \x{0631} ==> type CS (règle = R01)
        $k = 5, $str = َ \x{064e} ==> type VC (règle = R04)
        $k = 6, $str = ا \x{0627} ==> type VL (règle = R12)
        $k = 7, $str = ن \x{0646} ==> type CS (règle = R01)
        $k = 8, $str = ْ \x{0652} ==> type VC (règle = R06)
    Ligne => 7 [يِمْشِي]
      Mot يِمْشِي \x{064a}\x{0650}\x{0645}\x{0652}\x{0634}\x{0650}\x{064a}
        $k = 0, $str = ي \x{064a} ==> type CL (règle = R17)
        $k = 1, $str = ِ \x{0650} ==> type VC (règle = R05)
        $k = 2, $str = م \x{0645} ==> type CL (règle = R03)
        $k = 3, $str = ْ \x{0652} ==> type VC (règle = R06)
        $k = 4, $str = ش \x{0634} ==> type CS (règle = R01)
        $k = 5, $str = ِ \x{0650} ==> type VC (règle = R05)
    Ligne => 8 [سَاعَةْ]
      Mot سَاعَةْ \x{0633}\x{064e}\x{0627}\x{0639}\x{064e}\x{0629}\x{0652}
        $k = 0, $str = س \x{0633} ==> type CS (règle = R01)
        $k = 1, $str = َ \x{064e} ==> type VC (règle = R04)
        $k = 2, $str = ا \x{0627} ==> type VL (règle = R12)
        $k = 3, $str = ع \x{0639} ==> type CL (règle = R03)
        $k = 4, $str = َ \x{064e} ==> type VC (règle = R04)
        $k = 5, $str = ة \x{0629} ==> type CS (règle = R01)
        $k = 6, $str = ْ \x{0652} ==> type VC (règle = R06)
    Taisha:~/tttmp/hashcomp $ diff tb19_6.pl.log tb19_10.pl.log
    2a3,12
    >                               "\x{645}" => {
    >                                       'CL' => {
    >                                                 '2' => 1
    >                                               }
    >                                     },
    >                               "\x{634}" => {
    >                                       'CS' => {
    >                                                 '4' => 1
    >                                               }
    >                                     },
    12a23,27
    >                                     },
    >                               "\x{64a}" => {
    >                                       'CL' => {
    >                                                 '0' => 1
    >                                               }
    21a37,41
    >                                   "\x{636}" => {
    >                                           'CS' => {
    >                                                     '4' => 1
    >                                                   }
    >                                         },
    31a52,66
    >                                         },
    >                                   "\x{641}" => {
    >                                           'CL' => {
    >                                                     '2' => 1
    >                                                   }
    >                                         },
    >                                   "\x{62a}" => {
    >                                           'CS' => {
    >                                                     '0' => 1
    >                                                   }
    >                                         },
    >                                   "\x{644}" => {
    >                                           'CS' => {
    >                                                     '7' => 1
    >                                                   }
    34a70,74
    >                               "\x{628}" => {
    >                                       'CL' => {
    >                                                 '0' => 1
    >                                               }
    >                                     },
    44c84,94
    <                                     }
    ---
    >                                     },
    >                               "\x{647}" => {
    >                                       'CL' => {
    >                                                 '5' => 1
    >                                               }
    >                                     },
    >                               "\x{627}\x{644}" => {
    >                                         'CL' => {
    >                                                   '2' => 1
    >                                                 }
    >                                       }
    57a108,112
    >                               "\x{629}" => {
    >                                       'CS' => {
    >                                                 '5' => 1
    >                                               }
    >                                     },
    61a117,126
    >                                     },
    >                               "\x{639}" => {
    >                                       'CL' => {
    >                                                 '3' => 1
    >                                               }
    >                                     },
    >                               "\x{633}" => {
    >                                       'CS' => {
    >                                                 '0' => 1
    >                                               }
    69a135,139
    >                         "\x{645}" => {
    >                                 'CL' => {
    >                                           '0' => 1
    >                                         }
    >                               },
    73a144,148
    >                               },
    >                         "\x{639}" => {
    >                                 'CL' => {
    >                                           '2' => 1
    >                                         }
    82a158,167
    >                                   "\x{642}" => {
    >                                           'CL' => {
    >                                                     '2' => 1
    >                                                   }
    >                                         },
    >                                   "\x{634}" => {
    >                                           'CS' => {
    >                                                     '7' => 1
    >                                                   }
    >                                         },
    88a174,183
    >                                   "\x{648}" => {
    >                                           'CL' => {
    >                                                     '0' => 1
    >                                                   }
    >                                         },
    >                                   "\x{62a}" => {
    >                                           'CS' => {
    >                                                     '4' => 1
    >                                                   }
    >                                         },
    100a196,200
    >                                   "\x{631}" => {
    >                                           'CS' => {
    >                                                     '4' => 1
    >                                                   }
    >                                         },
    106a207,216
    >                                   "\x{646}" => {
    >                                           'CS' => {
    >                                                     '7' => 1
    >                                                   }
    >                                         },
    >                                   "\x{62a}" => {
    >                                           'CS' => {
    >                                                     '2' => 1
    >                                                   }
    >                                         },
    111c221,226
    <                                         }
    ---
    >                                         },
    >                                   "\x{627}\x{644}" => {
    >                                             'CL' => {
    >                                                       '0' => 1
    >                                                     }
    >                                           }
    118a234,238
    >                             "\x{62e}" => {
    >                                     'CL' => {
    >                                               '0' => 1
    >                                             }
    >                                   },
    121a242,246
    >                                             }
    >                                   },
    >                             "\x{64a}" => {
    >                                     'CL' => {
    >                                               '3' => 1
    Taisha:~/tttmp/hashcomp $

    Ca me semble le bon moment pour que tu vérifies que je n'ai pas fait de bêtises, et que le hash produit ainsi que les traces de debug correspondent bien à ce que tu attendrais...

    Je me suis peut-être un peu laissé emporter, et j'espère que les restructurations effectuées te conviennent Si ce n'est pas le cas dis le moi et on pourra peut-être revenir à une configuration plus proche de ton code initial (en corrigeant cependant les quelques bugs détectés). Tu trouveras en attachement l'ensemble des versions.

    Et on peut enfin s'attaquer à tes questions initiales . Pour commencer, j'ai quelques questions (je n'y connais rien en linguistique) : qu'est-ce que tu appelles un graphème ? Est-ce un caractère unique, ou bien une combinaison, comme \x{627}\x{644} (ال) ? Est-ce que l'ordre des règles est important ? Est-ce que plusieurs règles peuvent se déclencher pour un même caractère ? Par ailleurs, sous la forme actuelle, l'ordre des caractères est malcommode à récupérer dans le hash. Es-tu certaine que tu ne préfèrerais pas gérer chaque mot comme une liste de hashes, à raison d'un hash par caractère ou combinaison, dans lequel on pourraît par exemple mettre son type (entre autres informations) ?


    PS : j'ai commis cette restructuration au fil de l'eau et de manière hachée, au hasard des créneaux disponibles, et le jeu de test dont je dispose est très réduit. Il est tout à fait possible (probable ?) que j'aie commis des erreurs. Une manière de le détecter serait pour toi de tester les différentes versions du script (éventuellement rectifiées pour supprimer les entités HTML comme effectué ci-dessus) sur le corpus complet, et de comparer à chaque fois les fichiers de log produits. Si tu trouves des différences autres que celles attendues, n'hésite pas à revenir vers moi.
    Fichiers attachés Fichiers attachés

  5. #5
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Billets dans le blog
    1
    Par défaut
    Je n'ai pas tout lu en détail, mais tu as fait un sacré boulot. +1.

  6. #6
    Membre averti
    Femme Profil pro
    Inscrit en
    Janvier 2013
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Femme

    Informations forums :
    Inscription : Janvier 2013
    Messages : 53
    Par défaut
    Bonsoir cmcmc
    Merci beaucoup pour votre aide et pour les détails et les différents versions.
    Mais j'ai juste un autre probléme, aprés avoir remplir le hash je vais faire une comparaison avec le hash des régles et les autres hash des exceptions et des nombre.
    J'aimerais avoir comme résultat:
    تْفَضَّلْ T F AE DD DD AE L
    je vais vous expliquer comment j'ai générer cette phonétisation :
    Si le graphème (c'est l'unité de l'écrit correspondant à l'unité orale qu'est le phonème) suivi du SOKUN \x{0652} c'est le diacritique que va avez représenter par /ْ/ reste tel qu'il est (dans ce cas le graphème ث avoir comme phonème T) et si le graphème est suivi par FATHA \x{064E} ( /َ/ ) alors on ajoute le phonème AE après le phonème qui correspond au graphème qui porte FATHA (dans ce cas le graphème ف avoir comme phonème F suivi du AE) etc .. selon la base des règles.
    Si vous voulez j'ai le même programme mais avec un fichier xml qui génére la phonétisation (c'est à dire je stocke la segmentation dans un fichier xml) et puis je fais la comparaison entre ce fichier et les différents hash
    voici un extrait de mon programme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
     
    if ($mot !~/^(ال)/)
    	{
     
    		foreach my $twig_caractere ( $twig_mot->children('caractere') ) 
    	    {
    		    foreach my $graph ( keys %regles ) 
                {	
     
    				if (($twig_caractere->text()=~/ب/) and ($twig_caractere->next_sibling_text()=~/ال/))
    			    { 
    				    my $nextSibling = $twig_caractere->next_sibling_text(); 
    				    foreach my $cg ( keys %regles ) 
                        {
    					    if (($graph eq $twig_caractere->text) and ($nextSibling eq $cg))
    				        {
    						    #print {$fh_Aran} "$regles{$graph}";
    						    $phoneme=$phoneme." ".$regles{$graph . '|' . $cg};
    				        }
    				    }	
                    }
     
    			    if (($twig_caractere->text()=~/ي/) and ($twig_caractere->next_sibling_text()!~/[ن ظ ط ض ص ش س ر ز ذ د ت ث ة إ م ه آ ق ف  غ و ي ع ج ح خ ب أ ك ء ؤ ئ ا]/))
    			    { 
    				    if ($graph eq $twig_caractere->text) 
    				    {
    					    $phoneme=$phoneme." "."IY";
    				    }
     
                    }
    			    else
    			    {
    			        if (($twig_caractere->text()=~/ي/) and ($twig_caractere->next_sibling_text()=~/[ن ظ ط ض ص ش س ر ز ذ د ت ث ة إ م ه آ ق ف  غ و ي ع ج ح خ ب أ ك ء ؤ ئ ا]/))
    			        { 
    				        if ($graph eq $twig_caractere->text) 
    				        {
    					        $phoneme=$phoneme." ".$regles{$graph};
    				        }
                        } 
    			    }
    			    if (($twig_caractere->text()=~/إ/) and ($twig_caractere->next_sibling_text()=~/ي/))
    			    { 
    				    my $nextSibling = $twig_caractere->next_sibling_text(); 
    				    foreach my $cg ( keys %regles ) 
                        {
    				        if ($graph eq $twig_caractere->text and $cg eq $nextSibling) 
    				        {
    					        $phoneme=$phoneme." ".$regles{$graph . '|' . $cg};
    				        }
    				    }	
                    }
    			    else
    			    {
    			        if (($twig_caractere->text()=~/إ/) and ($twig_caractere->next_sibling_text()!~/ي/))
    			        { 
    				        if ($graph eq $twig_caractere->text) 
    				        {
    					        $phoneme=$phoneme." ".$regles{$graph};
    				        }
                        }
    			    }
    			    # Test pour le ALIF
    			    if (($twig_caractere->text()=~/\x{0627}/) and ($twig_caractere->prev_sibling_text()!~/[و]/))
    			    { 
    				    if ($graph eq $twig_caractere->text) 
    				    {
    					    $phoneme=$phoneme." ".$regles{ $graph};
    				    }
                    }
    			    if ((($twig_caractere->text()=~/[و]/) and ($twig_caractere->next_sibling_text()=~/\x{0627}/)) or (($twig_caractere->text()=~/[و]/) and ($twig_caractere->next_sibling_text()=~/$/)))
    			    { 
    				    my $nextSibling = $twig_caractere->next_sibling_text(); 
    				    foreach my $cg ( keys %regles ) 
                        {
    				        if ($graph eq $twig_caractere->text and $cg eq $nextSibling) 
    				        {
    					        $phoneme=$phoneme." ".$regles{$graph . '|' . $cg};
    				        }
    				    }	
                    }
    			    else
    			    {
    			        if (($twig_caractere->text()=~/\x{0627}/) and ($twig_caractere->next_sibling_text()=~/[و]/))
    			        { 
    				        my $nextSibling = $twig_caractere->next_sibling_text(); 
    				        foreach my $cg ( keys %regles ) 
                            {
    				            if ($graph eq $twig_caractere->text and $cg eq $nextSibling) 
    				            {
    					            $phoneme=$phoneme." ".$regles{$graph . '|' . $cg};
    				            }
    				        }	
                        }
    			    }
    				if (($twig_caractere->text()=~/[و]/) and ($twig_caractere->next_sibling_text()=~/ي/)) 
    			    { 
    				    my $nextSibling = $twig_caractere->next_sibling();
                        my $nextSibling1 = $nextSibling->next_sibling();			
    				    if ($graph eq $twig_caractere->text and $nextSibling->text()=~/ي/ and $nextSibling1->text()=~/\x{0627}/) 
    				    {
    					    $phoneme=$phoneme." "."UW";
    				    }
     
                    }
    				else
    				{
    			        if (($twig_caractere->text()=~/[و]/) and ($twig_caractere->next_sibling_text()!~/\x{0627}/) and $twig_caractere->prev_sibling_text()!~/\x{0627}/)
    			        { 
    				        if ($graph eq $twig_caractere->text ) 
    				       {
    					        $phoneme=$phoneme." ".$regles{$graph};
    				        }
    					}
                    }
    			    # Test pour le ALIF MAMDOUDA
    			    if ($twig_caractere->text()=~/[ى]/) #and ($twig_caractere->prev_sibling_text()=~/\x{064E}/))
    			    { 
    				    if ($graph eq $twig_caractere->text) 
    				    {
    					    $phoneme=$phoneme." ".$regles{ $graph};
    				    }
                    }
    			    #  Test pour les CL et CS
    			    if ($twig_caractere->text()!~/\x{0627}/)
    			    {
    				    if ($twig_caractere->text()!~/[و]/)
    				    {
    				        if ($twig_caractere->text()!~/إ/)
    				        {
    				            if ($twig_caractere->text()!~/[ي]/)
    				            {
    				                if ($twig_caractere->text()!~/\x{0651}/)
    			                    { 
    					                if ((( $graph eq $twig_caractere->text) and ($twig_caractere->att('type') eq "CL")) or (( $graph eq $twig_caractere->text) and ($twig_caractere->att('type') eq "C")) or (($graph eq $twig_caractere->text) and ($twig_caractere->att('type') eq "CS")))#or (( $graph eq $twig_caractere->text )and ($twig_caractere->att('type') eq "VL")))
    			                        {
    					                    $phoneme=$phoneme." ".$regles{$graph};
    					                }   
    		                        }	
    				                else
    			                    {
    					                my $prevSibling = $twig_caractere->prev_sibling_text();
    				                    if ( $graph eq $prevSibling) 
    			                        {
    					                    $phoneme=$phoneme." ".$regles{$graph};
    				                    }
    			                    }
    			                }
                            } 
                        }			
                    }
     
    		    }		
            }
    et voici un extrait du fichier xml:

    <Mot Num="2" Nom="تْفَضَّلْ">
    <caractere type="CS">ت</caractere>
    <caractere type="VC">ْ</caractere>
    <caractere type="CL">ف</caractere>
    <caractere type="VC">َ</caractere>
    <caractere type="CS">ض</caractere>
    <caractere type="VC">ّ</caractere>
    <caractere type="VC">َ</caractere>
    <caractere type="CS">ل</caractere>
    <caractere type="VC">ْ</caractere>
    </Mot>
    <Mot Num="3" Nom="خُويَا">
    <caractere type="CL">خ</caractere>
    <caractere type="VC">ُ</caractere>
    <caractere type="VL">و</caractere>
    <caractere type="CL">ي</caractere>
    <caractere type="VC">َ</caractere>
    <caractere type="VL">ا</caractere>
    </Mot>
    <Mot Num="4" Nom="مْعَ">
    <caractere type="CL">م</caractere>
    <caractere type="VC">ْ</caractere>
    <caractere type="CL">ع</caractere>
    <caractere type="VC">َ</caractere>
    </Mot>
    <Mot Num="5" Nom="وَقْتَاشْ">
    <caractere type="CL">و</caractere>
    <caractere type="VC">َ</caractere>
    <caractere type="CL">ق</caractere>
    <caractere type="VC">ْ</caractere>
    <caractere type="CS">ت</caractere>
    <caractere type="VC">َ</caractere>
    <caractere type="VL">ا</caractere>
    <caractere type="CS">ش</caractere>
    <caractere type="VC">ْ</caractere>
    </Mot>

    Merci une autre fois

  7. #7
    Membre chevronné Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Par défaut
    Bonsoir,

    je suis peut-être naïf mais il me semble que pour effectuer ces rapprochements il est préférable de traiter chaque mot comme une liste de caractères et non pas comme un hash. C'est ce qui est fait dans la version 11 attachée. La différence opérationnelle principale est dans set_type, où au lieu de remplir $thisword comme un hash
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
                    $thisword->{$str}{$type}{$k}++;
    on le remplit comme une liste
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
                    push @$thisword, { str => $str, type => $type};
    Ensuite pour la production de la phonétisation on procède comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    foreach my $word (keys %h ) {
        print {$fh_Aran} "$word ";
        foreach my $h (@{$h{$word}}) {
            my $phon = $regles{$h->{str}} || '-';
            print {$fh_Aran} " $phon";
        }
        print {$fh_Aran} "\n";
    }
    Comme je n'ai pas la base complète de règles le résultat est un peu vide chez moi mais le principe semble OK:

    Code x : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    يِمْشِي  - - - - - -
    تْفَضَّلْ  T - - - - - - - -
    بِاللهْ  B - - - -
    سَاعَةْ  - - - - - - -
    مْعَ  - - - -
    وَقْتَاشْ  - - - - T - - - -
    التْرَانْ  - T - - - - - -
    خُويَا  - - - -

    N'hésite pas à revenir vers moi si ce n'est pas clair.
    Fichiers attachés Fichiers attachés

Discussions similaires

  1. remplir un tableau avec un autre
    Par sandball22 dans le forum C
    Réponses: 28
    Dernier message: 20/04/2007, 16h13
  2. remplire un crystal report sans connexion avec sql server
    Par charaf dans le forum Windows Forms
    Réponses: 2
    Dernier message: 22/03/2007, 13h17
  3. Réponses: 35
    Dernier message: 21/03/2007, 10h36
  4. Réponses: 7
    Dernier message: 14/12/2006, 14h18
  5. Réponses: 9
    Dernier message: 15/05/2006, 16h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo