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 :

Substitution dans un élément matché


Sujet :

Langage Perl

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Inscrit en
    Juillet 2010
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 13
    Par défaut Substitution dans un élément matché
    Bonjour,

    Je souhaite pouvoir faire une substitution dans un élément matché, je ne sais pas si c'est possible.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    my $ligne = 'bonjour bla 1ope2 ; 3ope4 bla adieu';
     
    if($ligne =~ m/bla(.*?)bla/) {
        $1 =~ s/(.*?)ope(.*?)/$1 ope $2/g
    }
    perl me retourne :
    Modification of a read-only value attempted
    Y a-t-il une solution à ce problème ?
    Merci

  2. #2
    Membre chevronné Avatar de Beniou
    Homme Profil pro
    Inscrit en
    Novembre 2009
    Messages
    357
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2009
    Messages : 357
    Par défaut
    Il suffit de mettre le contenu du match $1 dans une variable pour faire ta substitution après. En effet, tu ne peux pas modifier cette variable directement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if($ligne =~ m/bla(.*?)bla/) {
       my $value = $1;
        $value =~ s/(.*?)ope(.*?)/$1 ope $2/g;
    }

  3. #3
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Par défaut
    Il est tout à fait possible de modifier un élément dans un chaine...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    my $ligne = 'bonjour bla 1ope2 ; 3ope4 bla adieu';
    if($ligne =~ m/bla(.*?)bla/) {
      $ligne =~ s/(bla.*?)ope(.*?bla)/$1 ope $2/g;
    }
    Après essai, il semble que seul le premier match soit correctement subsitué... je regarde après le café

  4. #4
    Membre habitué
    Inscrit en
    Juillet 2010
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 13
    Par défaut
    Citation Envoyé par Philou67430 Voir le message
    Il est tout à fait possible de modifier un élément dans un chaine...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    my $ligne = 'bonjour bla 1ope2 ; 3ope4 bla adieu';
    if($ligne =~ m/bla(.*?)bla/) {
      $ligne =~ s/(bla.*?)ope(.*?bla)/$1 ope $2/g;
    }
    Après essai, il semble que seul le premier match soit correctement subsitué... je regarde après le café
    Désolé mais cela ne fait pas la même chose, la question porte sur la modification de l'élément matché entre les deux "bla".
    Du coup ton code n'aura d'effet que sur le premier motif contenant "ope" (malgré l'option "g").

  5. #5
    Membre chevronné Avatar de Beniou
    Homme Profil pro
    Inscrit en
    Novembre 2009
    Messages
    357
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2009
    Messages : 357
    Par défaut
    Citation Envoyé par Philou67430
    Il est tout à fait possible de modifier un élément dans un chaine...
    Quand je dis qu'on ne pouvait pas modifier cette variable, je voulais parler bien sûr de $1 utilisée comme dans son exemple ou peut être me trompe-je encore ?

  6. #6
    Membre chevronné Avatar de Beniou
    Homme Profil pro
    Inscrit en
    Novembre 2009
    Messages
    357
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2009
    Messages : 357
    Par défaut
    En attendant la version de Philou, voici une version qui fonctionne mais qui n'est pas très esthétique...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    if($ligne =~ m/(.*bla)(.*?)(bla.*)/) {
      my $debut = $1;
      my $subst = $2;
      my $fin = $3;
      $subst =~ s/(.*?)ope(.*?)/$1 ope $2/g;
      $ligne = $debut.$subst.$fin;
    }
    Par contre cela ne marchera que si on ne trouve qu'une seule occurrence bla.. bla par ligne...

  7. #7
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Par défaut
    OK, j'ai compris en regardant à nouveau l'exemple : il y a plusieurs ope à modifier entre les bla ... bla. De fait, mon expression régulière se terminant par le 2e bla ne peut pas matcher plusieurs fois.

    Dans ce cas, effectivement, il convient de partager la ligne et de modifier l'élément avant de la reconstruire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #!/usr/bin/perl
     
    my $ligne = "bonjour bla 1ope2 ; 3ope4 bla adieu";
    my $l = $ligne;
     
    @l = split /(bla.*?bla)/, $ligne;
    foreach my $motif (@l) {
      if ($motif =~ /bla.*?bla/) {
        $motif =~ s/ope/ ope /g;
      }
    }
    $ligne = join "", @l;

  8. #8
    Membre habitué
    Inscrit en
    Juillet 2010
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 13
    Par défaut
    Merci pour ce début de réponse

    Citation Envoyé par Beniou Voir le message
    Il suffit de mettre le contenu du match $1 dans une variable pour faire ta substitution après. En effet, tu ne peux pas modifier cette variable directement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if($ligne =~ m/bla(.*?)bla/) {
       my $value = $1;
        $value =~ s/(.*?)ope(.*?)/$1 ope $2/g;
    }
    Effectivement, c'est une bonne idée, mais ça n'a aucun impact sur la ligne traitée, seulement sur $value.
    Peut-être y a-t-il moyen de réinjecter (en tenant compte du fait que plusieurs substitutions ont pu être faites ).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Substitution dans un .htaccess
    Par wahou85 dans le forum Apache
    Réponses: 2
    Dernier message: 13/01/2007, 01h25
  2. [CSS] Image de fond dans un élément <div>
    Par Yogui dans le forum Mise en page CSS
    Réponses: 5
    Dernier message: 16/05/2006, 13h05
  3. [XML] attribut dans l'élément racine
    Par gabychon dans le forum XML/XSL et SOAP
    Réponses: 2
    Dernier message: 27/04/2006, 14h44
  4. Limiter la saisie dans un élément texte
    Par manou.K dans le forum Oracle
    Réponses: 2
    Dernier message: 28/07/2005, 11h41
  5. Réponses: 4
    Dernier message: 03/03/2004, 11h04

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