Rechercher : dans
Par :

[Perl] Comparaison de caractères

Dernière réponse le 10 sep 2008 à 05:43:50 khaz, le 19 nov 2007 à 13:47:07 
 Signaler ce message aux modérateurs

Bonjour à tous,

j'ai un problème avec un script perl. Enfin lors d'une comparaison entre 2 chaines de caracteres visiblement identique, celle ci sont considérées comme étant différentes.

Voici ma comparaison :
$Compar = $BO{$cli}{$mod} cmp $SGI{$cli}{$mod};
print " comparaison : $Compar $BO{$cli}{$mod} et $SGI{$cli}{$mod} pour \n";

son résultat :
comparaison : -1
Location de T3, centre ville face mer§piscine, tennis sur place,§golf, casino, thalasso et cinéma à proximité.
Location de T3, centre ville face mer§piscine, tennis sur place,§golf, casino, thalasso et cinéma à proximité.


Et comment elles sont remplies a partir d'un fichier :
while ($Lig = <Fic>)
{
chomp $Lig;
($cli, $mod, $lig1, $lig2, $lig3) = split(/§/, $Lig);
$cli += 0;
$mod += 0;
$BO{$cli}{$mod} = "$lig1§$lig2§$lig3";
}
[...]
while ($Lig = <Fic>)
{
chomp $Lig;
($cli, $mod, $lig1, $lig2, $lig3) = split(/§/, $Lig);
$cli += 0;
$mod += 0;
if (! $BO{$cli}{$mod})
{
print Sortie "$cli-$mod\n";
$SGIseul ++;
}
else
{
$SGI{$cli}{$mod} = "$lig1§$lig2§$lig3";
}
}
if ($SGIseul == 0)
{
print Sortie "Aucun\n";
}




Vous auriez une piste?
Une fonction permettant de mettre en évidence les différences entre 2 chaines de caractères ?

Meilleures réponses pour « [Perl] Comparaison de caractères » dans :
PHP - Nettoyer une chaîne de caractères VoirVoici une fonction en PHP qui peut être assez pratique, surtout quand on fait de l'URL Rewriting. Cette fonction permet de transformer les caractères de n'importe quelle chaîne de caractères en chaîne non accentuée, en enlevant les caractères...
[CCM] Utiliser des caractères spéciaux VoirVous pouvez utiliser des caractères spéciaux dans vos messages sur les forums de CCM. Vous pouvez: Soit utiliser la table de caractères Windows (charmap.exe) et copier-coller les caractères dans le message. Soit utiliser les entités...
Utiliser des accents et autres caractères spéciaux VoirDans la plupart des langages de programmation, on ne peut utiliser directement les accents et autres caractères non-anglosaxon. La solution est l'unicode, une sorte de code universel. Par exemple pour afficher la chaine de caractères : " là, ça...
Perl - Caractéristiques du langage VoirFichier source, et interprétation Le fichier source d'un programme écrit en Perl est un simple fichier texte dont l'extension est par convention .pl. Ce fichier source doit être un fichier texte non formatté, c'est-à-dire un fichier texte dans sa...
Perl - les opérateurs VoirQu'est-ce qu'un opérateur? Les opérateurs sont des symboles qui permettent de manipuler des variables, c'est-à-dire effectuer des opérations, les évaluer, ... On distingue plusieurs types d'opérateurs : les opérateurs de calcul les...
Les chaînes de caractères en C++ VoirQu'est-ce qu'une chaîne de caractères ? Une chaîne de caractères (appelée string en anglais) est une suite de caractères, c'est-à-dire un ensemble de symboles faisant partie du jeu de caractères, défini par le code ASCII. En langage C++, une...

1

lami20j, le 19 nov 2007 à 14:21:35

Salut,

Vous auriez une piste?
Si tu peux donner ton fichier sur cjoint.com je pourrais tester

sinon tu peux faire une conversion des caractères en ASCII pour voir le caratère qui traine

Regarde danc cet exemple.
On a l'impression que les lignes sont identiques, en revanche quand je fais la conversion en ASCII je vois la différence (voir en gras)

lami20j@debserv:~/trash$ cat fic.txt
abcdef
abcdef
abcdef
lami20j@debserv:~/trash$ perl -ne 's/(.)/ord($1)/egs;print "$_\n"' fic.txt
97989910010110210
9798991001011023210
979899100101102910

la deuxième ligne a un espace à la fin (ASCII 32)
la 3ème une tabulation (ASCII 9)
lami20j

Répondre à lami20j

2

khaz, le 19 nov 2007 à 14:40:23

Après la conversion en caractères ascii, il y'a effectivement un probleme en fin de ligne .

[proexp@lrec11 samantha]$ perl -ne 's/(.)/ord($1)/egs;print "$_\n"' bopro3.csv
48484851495057541674848485116776111999711610511111032100101328451443299101110116114101321181051081081013210297991013210910111416711210511599105110101443211610111011010511532115117114321121089799101441671031111081024432999711510511011144321161049710897115115111321011163299105110233109973222432112114111120105109105116233461310
48484851495057541674848485016767111110103114232115443211523310910511097105114101115321161111171161013210839971101102331014616711210511599105110101443211610111011010511532115117114321121089799101461671031111081024432999711510511011144321161049710897115115111321011163299105110233109973222432112114111120105109105116233461310
[proexp@lrec11 samantha]$ perl -ne 's/(.)/ord($1)/egs;print "$_\n"' sgipro3.csv
484848514950575416748484850167671111101031142321154432115233109105110971051141011153211611111711610132108399711011023310146167112105115991051101014432116101110110105115321151171143211210897991014616710311110810244329997115105110111443211610497108971151151113210111632991051102331099732224321121141111201051091051162334610
484848514950575416748484851167761119997116105111110321001013284514432991011101161141013211810510810810132102979910132109101114167112105115991051101014432116101110110105115321151171143211210897991014416710311110810244329997115105110111443211610497108971151151113210111632991051102331099732224321121141111201051091051162334610

Pour mon premier fichier j'ai donc des retours chariots et des saut de lignes alors que dans le deuxieme, j'ai que les sauts de lignes.
Par contre, je m'interroge sur le chomp à présent : quel caractère supprime t'il ? le retour chariot ou le saut de ligne ?
Et du coup, comment faire pour que ma comparaison se fasse sans accroc malgré cette différence ?

En executant la commande file sur mes fichiers j'obtiens ceci :
bopro3.csv: UTF-8 Unicode text, with CRLF line terminators
sgipro3.csv: UTF-8 Unicode text

Vous sauriez quel format de fichier me permettrait d'homogénéiser le tout avec la commande iconv ?

Répondre à khaz

3

lami20j, le 19 nov 2007 à 14:46:49

Par contre, je m'interroge sur le chomp à présent : quel caractère supprime t'il ? le retour chariot ou le saut de ligne ?
voici ce que fait chomp
supprime toute fin de ligne correspondant à la valeur courante de $/ (connue aussi sous le nom de $INPUT_RECORD_SEPARATOR

dans ton cas il s'agit d'un problème classique: ton fichier qui a les lignes qui se finissent avec 1310 sont des fichiers qui viennent depuis Windows

tu peux faire s/\r//pour supprimer le RetourChariot (Carriage Return - code ASCII 13)

essaie

perl -ne 's/\r//;s/(.)/ord($1)/egs;print "$_\n"' bopro3.csv 
perl -ne 's/(.)/ord($1)/egs;print "$_\n"' sgipro3.csv 


lami20j

Répondre à lami20j

4

lami20j, le 19 nov 2007 à 14:55:33

Tu peux aussi ouvrir les fichier avec

open FiC, "<:crlf", "fichier1.txt"
       or die "E/S : $!\n";


qui permet la conversion de CRLF en LF en lecture et de LF en CRLF en écriture
lami20j

Répondre à lami20j

5

khaz, le 19 nov 2007 à 15:12:04

Merci beaucoup pour ton aide qui m'aura permis de cibler la cause du problème: l'encodage de mes fichiers.
En effet, comme je suis déjà amené à à convertir mes fichiers en entrée dans un certain encodage, je préfére trouver un encodage pertinent plutot que de modifier mon code.
J'ouvre un autre sujet sur ce point là.

Répondre à khaz

6

sipi, le 9 sep 2008 à 22:13:12

Salut voila, je suis tomber sur ce post car je cherche à transformer mes caractère 10 en 1310 par une commande du genre:
perl -ne 's/(.)/ord($1)/egs;print "$_\n"' monfichier.txt | sed 's/10/1310/g' | (((commande pour retourner en caractere normal soit inverse de perl -ne 's/(.)/ord($1)/egs;print "$_\n"' csup.txt))) > monfichier.txt


ca pourrait beaucoup m'aider
car j'ai une bonne petite quantité de fichier text à transcrire pour pouvoir les utiliser sur windows au boulot

Répondre à sipi

7

 lami20j, le 10 sep 2008 à 05:43:50

Salut,

Cas 1
- fichier Unix (fin ligne \n) vers fichier Win (fin ligne \r\n)

lami20j@debian:~$ cat -v fic1013.txt
ligne1
ligne2
ligne3
lami20j@debian:~$ perl -ne 's/(.)/ord($1)/seg;print "$_\n"' fic1013.txt
1081051031101014910
1081051031101015010
1081051031101015110
lami20j@debian:~$ perl -pi.orig -e 's/\n/\r\n/' fic1013.txt
lami20j@debian:~$ cat -v fic1013.txt
ligne1^M
ligne2^M
ligne3^M
lami20j@debian:~$ perl -ne 's/(.)/ord($1)/seg;print "$_\n"' fic1013.txt
108105103110101491310
108105103110101501310
108105103110101511310
lami20j@debian:~$ cat -v fic1013.txt.orig
ligne1
ligne2
ligne3
lami20j@debian:~$ perl -ne 's/(.)/ord($1)/seg;print "$_\n"' fic1013.txt.orig
1081051031101014910
1081051031101015010
1081051031101015110


Cas 2 - fichier Win (fin ligne \r\n) vers fichier Unix (fin ligne \n)
lami20j@debian:~$ perl -pi.orig -e 's/\r//' fic1013.txt
lami20j@debian:~$ cat -v fic1013.txt
ligne1
ligne2
ligne3
lami20j@debian:~$ perl -ne 's/(.)/ord($1)/seg;print "$_\n"' fic1013.txt
1081051031101014910
1081051031101015010
1081051031101015110
lami20j@debian:~$ cat -v fic1013.txt.orig
ligne1^M
ligne2^M
ligne3^M
lami20j@debian:~$ perl -ne 's/(.)/ord($1)/seg;print "$_\n"' fic1013.txt.orig
108105103110101491310
108105103110101501310
108105103110101511310
lami20j@debian:~$


Toujours en Perl il y a aussi la possibilité d'utiliser la couche E/S :ctrlf

open FILE ,"<:crlf", "fichier.txt"; # ouvrir le fichier en lecture, effectue les substitutions de CRLF
                                    #en saute de ligne et vice versa en fonction de OS utilisé 



Une autre alternative c'est d'utiliser les commandes dos2unix et unix2dos.
Pour la distribution Debian Etch il faut installer le paquet tofrodos :
aptitude install tofrodos



106485010510997108

Répondre à lami20j
Collection CommentÇaMarche.net