OVH Cloud OVH Cloud

Aide debutant Perl Merci

5 réponses
Avatar
laurent860
Bonjour
dans un fichier xml je voudrais replacer la chaine
"<param-value>TOTO</param-value> " qui se trouve APRES
"<param-name>test.instance</param-name>"

par <param-value>TOTO</param-value>




Fichier Test.xml
<init-param>
<param-name>test.instance</param-name>
<param-value>TOTO</param-value>
</init-param>
<init-param>
<param-name>VERSION</param-name>
<param-value>1</param-value>
</init-param>
Merci d'avance

5 réponses

Avatar
Le_T
Bonjour

Tu peux le faire via une expression standard (regexp):

(euh... tu es sur de vouloir remplacer par ca? puisque c'est la meme
chose!)

$tachaine =~
s/(.+)?(<param-name>test.instance</param-name>)$chainearemplacer(.+)?/$1. $2.$chainequiremplace.$3/gi;

on dissèque?

=~ signifie expression régulière

s/arg1/arg2/mod; va remplacer arg1 par arg2 selon certaines règles et
selon mod

(.+)? signifie : tout caractère répeté plus d'une fois, le tout
repété un nombre inconnu de fois (en gros, n'importe quelle chaine
avant l'expression suivante)

$1 correspond a ce qui se trouve entre la première parenthèse (ici ta
chaine qui precède <param-name>test. ... )

$2 c'est la deuxième parenthèse

etc..

g signifie que tu va faire la recherche sur toutes les occurences de la
chaine
i signifie que tu es insensible a la casse

++

Le_T
Avatar
J.Pierre Pourrez
Le Thu, 29 Sep 2005 03:38:36 -0700, Le_T a écrit :

Bonjour

Tu peux le faire via une expression standard (regexp):

(euh... tu es sur de vouloir remplacer par ca? puisque c'est la meme
chose!)

$tachaine =~
s/(.+)?(<param-name>test.instance</param-name>)$chainearemplacer(.+)?/$1.$2.$chainequiremplace.$3/gi;


Soit test.xml le fichier à transformer:

perl -i.bak -pe 's|(<param-value>)TOTO(</param-value>)|$1TITI$2|gi'
test.xml

A utiliser avec find si plusieurs fichiers à traiter sous linux.

on dissèque?


On lit le manuel:
perldoc perlre

s/arg1/arg2/mod; va remplacer arg1 par arg2 selon certaines règles et
selon mod


On peut avantageusement remplacer "/" par un autre caractère, surtout si
on doit traiter du html, xml, ou autre langage à balises

Pour les nuls en anglais, c'est par là :
http://perl.enstimac.fr/DocFr/perlre.html

Bon courage
Jean-Pierre

Avatar
Michel Rodriguez
laurent860 wrote:

dans un fichier xml je voudrais replacer la chaine
"<param-value>TOTO</param-value> " qui se trouve APRES
"<param-name>test.instance</param-name>"


Juste une remarque: pour traiter du XML, le plus correct c'est
d'utiliser des outils XML.

Pour repondre d'avance aux remarques inevitables sur les perfos: dans
ton cas ca sera probablement plus lent que d'utiliser des regexps, mais
ca sera tres probablement plus correct (cf la celebre remarque, citee de
memoire: "si le but est d'arriver a un resultat faux le plus vite
possible, il fallait le preciser dans les specs"). En plus utiliser un
parseur, ca permet de verifier que le XML traite est bien-forme, ce qui
n'est pas toujours le cas.

Donc un exemple, avec of course XML::Twig:

#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;

my $TOTO= "TOTO"; # pour montrer comment on quote proprement
l'expression plus bas
my $TATA= "TATA";

XML::Twig->new( twig_handlers => { 'init-param' => &init_param, },
pretty_print => 'indented',
)
->parse( *DATA) # ou parsefile( 'text.xml')
->flush # pour finir d'imprimer
;

exit;

# sub appelee pour chaque init-param
sub init_param
{ my( $twig, $init_param)= @_;

# c'est ici que tout se passe, il y a d'autres manieres de
# trouver les elements a remplacer, par example avec une
# mega requete XPath (en utilisant XML::Twig::XPath) que j'ai
# la flemme de chercher
if( ($init_param->field( 'param-name' ) eq 'test.instance')
&& (my $value= $init_param->first_child(
qq{param-value[string()="$TOTO"]}
)
)
)
{ $value->set_text( $TATA); }
$twig->flush; # ca imprime le document jusqu'a l'element init_param
# et ca libere la memoire
}

__DATA__
<doc>
<init-param>
<param-name>test.instance</param-name>
<param-value>TOTO</param-value>
</init-param>
<init-param>
<param-name>VERSION</param-name>
<param-value>1</param-value>
</init-param>
<init-param>
<param-name>VERSION</param-name>
<param-value>TOTO</param-value>
</init-param>
</doc>

Avatar
Paul Gaborit
À (at) Thu, 29 Sep 2005 19:56:22 +0200,
"J.Pierre Pourrez" écrivait (wrote):
Pour les nuls en anglais, c'est par là :
http://perl.enstimac.fr/DocFr/perlre.html


Cette doc est complète mais un peu ardue pour débuter. Citons donc
aussi :

- perlrequick - Les expressions rationnelles Perl pour les impatients
<http://perl.enstimac.fr/DocFr/perlrequick.html>

- perlretut - Tutoriel des expressions rationnelles en Perl
<http://perl.enstimac.fr/DocFr/perlretut.html>

Et bien sûr la FAQ :

- perlfaq6 - Expressions rationnelles
<http://perl.enstimac.fr/DocFr/perlfaq6.html>

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

Avatar
Le_T
perl -i.bak -pe 's|(<param-value>)TOTO(</param-value>)|$1TITI$2|gi'
test.xml


Ce qui n'est jamais que la version ligne de commande de ce que j'ai
proposé...

Et meme si on traite du langage a balise, il est plus 'universel' de
mettre des /, quitte a utiliser l'échappement...

Le_T