Remplacer caractères héxa : PERL - Perl - Programmation
Marsh Posté le 29-07-2010 à 13:55:01
$machaine =~ s/\x0D\x0A\x46/\x45/g;
A+,
Marsh Posté le 29-07-2010 à 20:32:01
gilou a écrit : $machaine =~ s/\x0D\x0A\x46/\x45/g; |
merci mais ça ne marche pas.
Pour tester j'ai créer un programme en vert ça marche en rouge ça marche pas.
Donc un hexa ok plus de 2 pas ok
Code :
|
Rmq : J'utilise PsPad pour écrire des hexa. D'abord j'écris n'importe quoi dans mon fichier puis je remplace avec PsPadHEX certains caractères.
Marsh Posté le 29-07-2010 à 21:08:32
Bien sur que la, ca va pas marcher, puisque tu ouvres ton fichier en mode ligne à ligne, et que dans ton pattern recherché, il y a un caractère de fin de ligne (\x0A) (tes hexa substitués, c'est "\r\nF" ).
Il n'a été dit nulle part dans ta présentation initiale du problème, que ce que tu voulais substituer provenait d'une boucle de lecture de fichier, et vu qu'il y avait un \n au milieu de ton pattern cherché, il semblait même illogique que ce soit le cas.
Tu as deux possibilités:
Soit tes fichiers sont petit en mémoire, et tu lis tout ton fichier dans une variable texte pour lui appliquer la substitution:
Code :
|
Soit il faut avancer ligne a ligne et éclater ton pattern recherché en deux, celui avant la fin de ligne /\r\n$/ et celui après /^F/
et faire de une boucle qui teste lorsqu'une ligne a le bon pattern, si la ligne suivante l'a aussi on fait la substitution.
C'est plus coton (il faut mémoriser la ligne précédente et ne pas l'envoyer tout de suite en sortie) mais pas bien dur.
Ne pas oublier la aussi le binmode après ouverture du fichier, sinon, on ne verra jamais passer un \x0D\x0A.
A+,
Marsh Posté le 02-08-2010 à 12:22:38
Merci pour ta réponse.
J'ai trouvé , c'était très simple en fait. Dans perl il suffit de rajouter des crochets entre \r\n [\x0D\x0A]
Code :
|
Marsh Posté le 02-08-2010 à 13:50:47
Citation : il suffit de rajouter des crochets |
Euh non, c'est juste totalement faux, ça.
C'est pas la même expression régulière:
\x01[\x0D\x0A] c'est la même chose que \x01(\x0D|\x0A) c'est à dire \x01(\r|\n) et c'est donc pas du tout pareil que \x01\r\n
L'écriture entre [] n'a d'intérêt que si on fait un range [\x0A-\x0D] ou une négation [^\x0A]
Pourquoi le code que tu as écrit a des chances de marcher (sous dos windows)
1) manifestement, tu n'ouvres pas le fichier en mode binaire, donc les \r\n sont remappés par perl automatiquement en \n
donc tu remplacerait ton expression x01[\x0D\x0A] par x01\x0A que ça marcherait pareil
Donc effectivement, après ce remappage automatique, si on veut chercher ce qui est comme \x01\r\n dans le fichier, il va falloir chercher \x01\n
Et comme maintenant, avec ton \x01[\x0D\x0A] tu ne cherches plus comme avant \x01\x0D\x0A mais \x01(\x0D|\x0A) ce qui équivaut à (\x01\x0D|\x01\x0A) la seconde alternative \x01\x0A ie \x01\n va matcher ton \x01\r\n après le remappage de perl en \x01\n
Si tu avais lu ma réponse précédente et ouvert le fichier en mode binaire, il y aurait pas de remappage, et chercher \x01\x0D\x0A marcherait très bien.
2) ce coup ci, en mode lecture ligne à ligne, tu ne cherches plus une expression régulière avec un \n au milieu (ce qui ne pouvait pas être matché), mais avec un \n à la fin
Donc effectivement, ce coup ci, ça va pouvoir être matché, contrairement à ce que tu faisais avant (ou tu voulais un \x46 en début de ligne suivante)
Donc si ça marche maintenant, c'est pas du tout pour les raisons que tu donnes.
A+,
Marsh Posté le 02-08-2010 à 17:36:17
Autant pour moi!
Je te remercie pour tes explications d'expert.
Donc si j'ai un \n au milieu de l'expression régulière je procède comment?
Par exemple si j'ai FR\r\nANG que je veux remplacer par FR\r\nENG
je procède comme cela car ça n'a pas l'air de marcher :
Code :
|
Merci.
A+
Marsh Posté le 02-08-2010 à 19:53:08
Comme je te l'ai dit, tu peux pas si tu as ça dans une lecture ligne a ligne, car ton while (<FIC> ) va d'abord chopper le FR\r\n puis le ANG puisque ça lit ligne à ligne.
Comme je te l'avais indiqué, il y a deux méthodes:
Tout lire dans une seule grande ligne (pas possible si le fichier est trop gros).
On fait
Code :
|
1) on met dans un bloc {} sinon, ça risque de foutre le bordel ailleurs
2) on fait local( $/ ) ; pour lire sans s'arrêter a chaque \r\n (windows) ou \n (unix) cette redéfinition étant limitée au bloc
3) on lit tout en un seul coup dans une variable
4) on fait le remplacement sur le contenu de la variable
5) on sauve la variable modifiée dans le fichier de sortie.
L'autre méthode, c'est de procéder en deux temps; On cherche /FR\r\n$/ et quand on a trouvé ça, on le mémorise pour voir si la ligne suivante commence par /^ENG/ et si oui, on fait le remplacement:
Code :
|
Note que j'ai fait du code pédagogique, mais perso, ce serait my $ligprec; en ligne 2 et undef $ligprec; en ligne 22 que j'écrirais dans du vrai code.
A+,
Marsh Posté le 29-07-2010 à 10:33:38
Bonjour,
Je veux remplacer plusieurs caractères hexa (plus de 2) par un ou plusieurs autres caractères héxa avec perl.
Exemple :
remplacer 0D0A46 par 45
Apparement avec \x sous perl ça marche que pour un seul caractère hexa!
Avez-vous des solutions?
Merci