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 :

remplacer une variable par sa valeur dans une chaine


Sujet :

Langage Perl

  1. #1
    Membre du Club
    Inscrit en
    Mai 2002
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 47
    Points : 52
    Points
    52
    Par défaut remplacer une variable par sa valeur dans une chaine
    contexte: variables existantes connues au moment de l'execution
    WS_SERVER = lzweb6458
    IN_SERVER = lzweb6458
    APPME_SERVER = lzapp6458
    QUOTE_SERVER = lzquo6458
    BAT_SERVER = lzbat6458

    ...
    partie du code que je ne comprend pas :

    print "avant : ".$val."\n";
    $val =~ s/(\$[^ ]*)/$1/eg;
    print "apres :".$val."\n";
    ...

    le resultat est :
    avant : $WS_SERVER $IN_SERVER $APPME_SERVER $QUOTE_SERVER $BAT_SERVER
    apres : $WS_SERVER $IN_SERVER $APPME_SERVER $QUOTE_SERVER $BAT_SERVER
    ce que j'aurai voulu obtenir
    avant : $WS_SERVER $IN_SERVER $APPME_SERVER $QUOTE_SERVER $BAT_SERVER
    apres : lzweb6458 lzweb6458 lzapp6458 lzquo6458 lzbat6458
    deux question : quelle est la notion technique qui designe le mechanisme que je veux utiliser ( j'aurai appelé ca une indirection mais je ne suis pas sur.

    la deuxieme est : ou est mon erreur ?

  2. #2
    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
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Je ne suis pas 100% sûr de bien comprendre ce que tu veux faire, car tu ne donnes qu'une partie de ce que tu as essayé de faire (mets le code complet, si possible), mais il me semble que tu veux remplacer le nom des variables par leur contenu. Cela s'appelle plutôt un déréférencement qu'une indirection (c'est-à-dire l'opération inverse d'une indirection), bien que l'on n’utiliserait en fait pas ce terme dans un cas aussi simple (c'est plutôt réservé aux pointeurs en C ou aux références en Perl). Dans ce genre de cas, on parlerait sans doute plutôt d'interpolation de la variable: il y a des contextes ou le nom de la variable reste un nom de variable, et d'autres où il est substitué par son contenu. J'y reviens plus bas.

    Mais regarde tout de suite si la session suivante sous le débugger Perl ne fait pas tout simplement ce que tu essaies de faire de façon bien compliquée:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      DB<1> $WS_SERVER = "lzweb6458";
     
      DB<2> $IN_SERVER = "lzweb6458";
     
      DB<3> $APPME_SERVER = "lzapp6458";
     
      DB<4> $result = "$WS_SERVER $IN_SERVER $APPME_SERVER ";
     
      DB<5> print $result
    lzweb6458 lzweb6458 lzapp6458
    Il me semble que c'est ce que tu voulais obtenir (à part le fait que j'ai abrégé par paresse).

    Je reviens sur l'interpolation de la variable: suppose que tu veuilles, dans le cadre d'un debugage de ton programme, imprimer à un moment donné le nom et la valeur de tes différentes variables, pour vérifier qu'elles contiennent ce à quoi tu t'attends. Dans ce cas, tu pourrais imprimer (après l'exécution des lignes ci-dessus) les choses suivantes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      DB<7> print '$WS_SERVER = ', $WS_SERVER;
    $WS_SERVER = lzweb6458
     
      DB<8> print '$IN_SERVER = ', "$IN_SERVER \n";
    $IN_SERVER = lzweb6458
     
      DB<9> print '$result = ', $result,, "\n";
    $result = lzweb6458 lzweb6458 lzapp6458
     
      DB<10>
    Comme tu peux le voir, l'instruction

    imprime le nom de la variable et le signe =, alors que l'expression

    imprime le contenu de la variable (et un retour à la ligne).

    La différence vient de l'utilisation dans un cas d'apostrophes (single quotes), qui ne font pas d'interpolation (la chaine de caractères est imprimée exactement telle quelle), et dans l'autre cas des guillemets (doubles quotes) qui font l'interpolation, c'est-à-dire remplacent le nom de la variable pas son contenu.

  3. #3
    Membre du Club
    Inscrit en
    Mai 2002
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 47
    Points : 52
    Points
    52
    Par défaut
    Il s'agit en gros de faire un parsing de fichier d'environnement ksh.

    le fichier d'env contient donc entre autre les 3 lignes suivantes :
    $WS_SERVER=lzweb6458
    $IN_SERVER=lzweb6458
    $APPME_SERVER=lzapp6458 lzapp6459
    $SETRELEASE_SERVER=${WS_SERVER} ${IN_SERVER} ${APPME_SERVER}
    Voici la boucle de parsing qui analyse cette partie du fichier d'environnement ( elle n'est peut etre pas optimisée pour l'instant mais j'ai voulu faire simple
    while (my $ligne=<env_rc>){
    if ( $ligne =~ /SERVER/ ){
    my $var = my $val = $ligne;
    $var =~ s/([^=]*).*$/$1/;
    $var =~ s/\n//g;
    $val =~ s/$var=\"(.*)\"$/$1/;
    $val =~ s/[\n,},{]//g;
    $val =~ s/(\$[^ ]*)/"$1"/eg;
    print "$var : $val \n";
    }
    }
    avec ça j'arrive au resultat suivant
    $WS_SERVER=lzweb6458
    $IN_SERVER=lzweb6458
    $APPME_SERVER=lzapp6458 lzapp6459
    SETRELEASE_SERVER : $WS_SERVER $IN_SERVER $APPME_SERVER
    mai j'aurai souhaité obtenir :

    $WS_SERVER=lzweb6458
    $IN_SERVER=lzweb6458
    $APPME_SERVER=lzapp6458 lzapp6459
    SETRELEASE_SERVER : lzweb6458 lzweb6458 lzapp6458 lzapp6459
    je pense que le problème vient de la ligne indiquée en rouge mais je ne vois pas comment la modifier

  4. #4
    Membre régulier
    Homme Profil pro
    Inscrit en
    Juillet 2002
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 87
    Points : 92
    Points
    92
    Par défaut
    Bonjour,

    la ligne en rouge ne match pas les accolades.
    moi je testerai ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $val =~ s/(\$\{*\})/"$1"/eg;

  5. #5
    Membre du Club
    Inscrit en
    Mai 2002
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 47
    Points : 52
    Points
    52
    Par défaut
    while (my $ligne=<env_rc>){

    if ( $ligne =~ /SERVER/ ){
    my $var = my $val = $ligne;
    $var =~ s/([^=]*).*$/$1/;
    $var =~ s/\n//g;
    $val =~ s/$var=\"(.*)\"$/$1/;
    $val =~ s/[\n,},{]//g;
    $val =~ s/(\$[^ ]*)/"$1"/eg;
    print "$var : $val \n";
    }

    }
    La ligne en vert s'occupe de supprimer les accolades , je n'ai pas de probleme de matching mais plutot d'arriver dans la substitute string a récuperer le résultat que je veux.

    pour simplifier a l'extreme le probleme pourrait se résumer a ca :

    $STR1='$STR2'
    $STR2=ABC
    $STR1 =~ s/(.*)/$1/
    print "STR1 : $STR1"
    le resultat attendu etant le suivant :
    STR1 : ABC
    alors que je n'arrive a obtenir que le suivant :
    STR1 : $STR2

  6. #6
    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
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    De ce que je comprends, la variable $WS_SERVER n'est jamais créée, elle ne risque pas d'être interpolée (pareil pour les autres).

    Le plus simple est d'utiliser un hash pour stocker les valeurs des différents éléments( le hash %valeurs ci-dessous)

    Je trouve ton code bien compliqué et ne comprends pas tout ce que tu essaies de faire avec des substitutions successives, mais je l'ai laissé tel quel et n'ai changé que ce qui est nécessaire pour ton objectif:

    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
    my %valeurs;
    while (my $ligne=<DATA>){
    	if ( $ligne =~ /SERVER/ ){
    		chomp $ligne; # supprime saut de ligne
    		$ligne =~ s/\r//; # supprime retour chariot Windows le cas échéant
    		my $var = my $val = $ligne;
    		$var =~ s/([^=]*).*$/$1/;
    		$var =~ s/\n//g;
    		$val =~ s/$var=\"(.*)\"$/$1/;
    		$val =~ s/[\n,},{]//g;
    		$val =~ s/(\$[^ ]*)/"$1"/eg;
    		if ($ligne =~ /^\$SETRELEASE/ ) {
    		   	$val =~ s/([ =])(\$[^ ]+)/"$1$valeurs{$2}"/eg; 
    		} else {
    			$valeurs{$var} = (split /=/, $val)[1];
    		}
    		print "$var : $val \n";
    	}
    }
    __DATA__
    $WS_SERVER=lzweb6458
    $IN_SERVER=lzweb6458
    $APPME_SERVER=lzapp6458 lzapp6459
    $SETRELEASE_SERVER=${WS_SERVER} ${IN_SERVER} ${APPME_SERVER}
    Ce qui me donne le résultat suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ perl  SERVER.pl
    $WS_SERVER : $WS_SERVER=lzweb6458
    $IN_SERVER : $IN_SERVER=lzweb6458
    $APPME_SERVER : $APPME_SERVER=lzapp6458 lzapp6459
    $SETRELEASE_SERVER : $SETRELEASE_SERVER=lzweb6458 lzweb6458 lzapp6458 lzapp6459

Discussions similaires

  1. Récupération de la valeur d une variable elle même contenue dans une variable
    Par guiplongeur dans le forum Shell et commandes GNU
    Réponses: 3
    Dernier message: 16/03/2015, 17h23
  2. Réponses: 3
    Dernier message: 03/01/2012, 12h16
  3. Réponses: 3
    Dernier message: 13/12/2009, 18h04
  4. Remplacer des balises par des valeurs dans une String
    Par RadicalBob dans le forum Langage
    Réponses: 4
    Dernier message: 26/04/2007, 16h22
  5. Réponses: 2
    Dernier message: 19/04/2007, 16h26

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