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 :

RegEx - Ignorer des bloques


Sujet :

Langage Perl

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 14
    Par défaut RegEx - Ignorer des bloques
    Bonjour,

    Je souhaites sélectionner toutes les expressions de la forme xx=yy et qui se trouvent en dehors d'accolades. Par exemple dans

    a=5 { xxxx y=7 zz u=8 oo } iiii b=7

    ne sera sélectionné que a=5 et b=7.

    J'imagine qu'il faut utiliser lookahead et lookbehind mais je ne vois pas vraiment comment

    Merci !

  2. #2
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2013
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2013
    Messages : 247
    Par défaut
    est ce que tu peux avoir plusieurs accolades sur une même ligne?

    cette regex te permet déjà d'avoir ce qui se trouve en dehors des accolades
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    my $l='a=5 { xxxx y=7 zz u=8 oo } iiii b=7'; 
    if ( $l =~ /(.*)\{(.*)\}(.*)/ ){ 
         print "$1 // $3\n";
    }
     
    -->a=5  //  iiii b=7
    Ensuite, tout dépend du format de la ligne alors pourrais tu indiquer si tu peux avoir plusieurs xx=yy avant et/ou plusieurs xx=yy après '{}', plusieurs accolades...

  3. #3
    Membre chevronné Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Par défaut
    Bonjour WilMon,

    J'imagine qu'il faut utiliser lookahead et lookbehind mais je ne vois pas vraiment comment
    regarde plutôt du côté de (?PARNO) (?-PARNO) (?+PARNO) (?R) (?0) dans perlre. Tu y trouveras une expression régulière permettant d'isoler un un groupe de parenthèses imbriquées, qu'il est facile d'adapter pour des accolades.

    Dans ton cas les accolades semblent jouer le rôle de commentaires. Une stratégie possible consiste à utiliser dans un premier temps l'expression régulière ci-dessus pour les filtrer (les éliminer du texte inital), et faire dans une seconde étape les recherches sur le texte ainsi simplifié.

    Par contre tu auras besoin d'un perl récent (qui comprenne (?PARNO)). Si les accolades ne sont pas imbriquées tu peux t'en sortir avec la même stratégie générale en utilisant une expression régulière plus simple et qui sera compréhensible pour les anciens perls.

    N'hésite pas à revenir à la charge si ça ne te paraît pas clair.

  4. #4
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 359
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 359
    Par défaut
    Bonjour,
    Surtout que cela peut se compliquer si l'on doit considérer les cas du type:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    a=5 {
    b=6
    c=7
    } d=8

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 14
    Par défaut
    Merci pour vos réponses !

    Pour être plus clair je vais expliquer mon problème. Je souhaites en fait parser du code R pour repérer toutes les affectations de variables réalisées en dehors d'accolades ou de parenthèses. Par exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    a = 5
     
    f1 = function() {
    b=1
    c=2
     
    try({eval(parse(text='a'))})
     
    return(b+c)
    }
     
    c=7
    je devrais avoir
    a = 5 et c = 7

    Les parenthèses et accolades peuvent donc être imbriquées.
    Merci cmcmc pour l'astuce de PARNO je ne connaissais pas cette manière, avec ça il me suffirait en effet de faire une première passe ou je supprimerais les parties inintéressantes puis une seconde ou je récupère les affectations.
    Mais est-il possible de regrouper ces deux étapes en une seule regex ? (j'en demande peut être un peu trop là )

  6. #6
    Membre chevronné Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Par défaut
    Citation Envoyé par WilMon Voir le message
    ...
    Les parenthèses et accolades peuvent donc être imbriquées.
    Merci cmcmc pour l'astuce de PARNO je ne connaissais pas cette manière, avec ça il me suffirait en effet de faire une première passe ou je supprimerais les parties inintéressantes puis une seconde ou je récupère les affectations.
    Mais est-il possible de regrouper ces deux étapes en une seule regex ? (j'en demande peut être un peu trop là )
    Je n'ai pas le temps de regarder maintenant. Peut être, mais sans doute au détriment 1) de la clarté, 2) des performances...

    quelque chose comme (non testé) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    my $braces = qr/({(?:[^{}]++|(?-1))*+})/;
    my $assign = ...; # affectation
     
    while ($text =~ /(:?$braces|.*?)*?($assign)/msg) {
        # faire quelque chose de $1
    }
    L'alternation (|) en particulier peut poser des problèmes.

    Tu peux peut être aussi essayer de virer le /g et de capturer les affectations au fur et à mesure via (?{...}) dans une expression régulière qui couvrirait l'ensemble de tes fichiers d'entrée (exemple ici).

  7. #7
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2013
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2013
    Messages : 247
    Par défaut
    si on considère que tu as un fichier tu peux essayé ça:

    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
    open(FH_IN, $file) or die "Ouverture fichier impossible\n";
    my $enrg = 'ok';
    while (<FH_IN>){
         if ( $_ =~ /\{/ ){
              $enrg = 'ko';
              next;
         }
         elsif ( $_ =~ /\}/ ){
              $enrg = 'ok';
              next;
         }
         elsif ( $enrg eq 'ok' and $_ =~ /((\w+)\s?=\s?(\d+))/ ){
              print "Affectation: $1\n";
         }
    }
    Résultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    -bash-3.00$ perl test.pl
    Affectation: a = 5
    Affectation: c=7
    Je repasserai pour essayer d'optimiser tout ça.

  8. #8
    Membre chevronné Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Par défaut
    en plus il semble qu'il faille filtrer les définitions de fonctions... J'aurais tendance à rester sur la version en deux passes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # parse2.pl
    use strict;
    use warnings;
    use 5.018;
     
    my $braces = qr/({(?:[^{}]++|(?-1))*+})/;
    my $left   = qr/\w+/; # a raffiner
    my $right  = qr/\d+/; # qu'est ce qu'on peut faire figurer en partie droite ? quid de function ... ?
    my $assign = qr/$left\s*=\s*$right/;
     
    say for do { local $/; <> } =~ s/$braces//msgr =~ m/$assign/msg;
    qui donne pour ton exemple
    Taisha:~/tttmp/ignorer_les_bloques $ perl parse2.pl filein
    a = 5
    c=7
    Taisha:~/tttmp/ignorer_les_bloques $

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 14
    Par défaut
    Ok je pense que je vais faire comme tu as dis cmcmc. Merci !

Discussions similaires

  1. [Regex] gestion des accents dans un mot
    Par joseph_p dans le forum Collection et Stream
    Réponses: 5
    Dernier message: 10/05/2006, 09h04
  2. [Requete] Comment ignorer des lignes avec un LOAD DATA
    Par frangin2003 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 09/11/2005, 12h14
  3. drop en ignorant des tables
    Par daguet dans le forum Requêtes
    Réponses: 2
    Dernier message: 25/10/2005, 15h14
  4. [Doxygene] Ignorer des fichiers
    Par chronos dans le forum Autres éditeurs
    Réponses: 1
    Dernier message: 28/07/2005, 11h24
  5. [FORMS9i] gestion des bloques
    Par Orameur dans le forum Forms
    Réponses: 12
    Dernier message: 06/10/2004, 12h32

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