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 :

Problème avec les expressions régulières


Sujet :

Langage Perl

  1. #1
    Membre du Club Avatar de philouelgeek
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    60
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 60
    Points : 49
    Points
    49
    Par défaut Problème avec les expressions régulières
    Salut,

    J'ai un fichier C de la forme suivante :

    Code c : 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
     
    /****************
     *CONSTANTES
     *****************/
    #define blanc 0
     
    /****************
    *SERVICES INTERNES
    *****************/
    void PBA_Si_ConvertirCouleur
          (CHAR CouleurIn,
           INT32 CodeCouleur,
           CHAR CouleurOut);
     
    void PBA_Si_RecupererCouleur
          (INT32 CodeCouleur,
           CHAR Couleur);
    Je souhaiterai récupérer les lignes contenant les _Si_, donc par exemple ici récupérer :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void PBA_Si_ConvertirCouleur
          (CHAR CouleurIn,
           INT32 CodeCouleur,
           CHAR CouleurOut);
    void PBA_Si_RecupererCouleur
          (INT32 CodeCouleur,
           CHAR Couleur);
    Voici mon code :
    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
    25
    26
    27
    28
    29
    30
     
    ## MODULES
    use strict;
     
    ## VARIABLES
        # Scalaires
    my $localpath = `pwd`;
    my $fic_a_verifier = "COULEUR.c";
    my $texte_fic_a_verifier = "";
     
     
        # Tableaux
    my @fic_a_verifier = ();
     
     
    ## PROGRAMME PRINCIPAL
     
    open FILE_VERIF,"<".$fic_a_verifier or die "Impossible d'ouvrir le  fichier $fic_a_verifier !";
    @fic_a_verifier = readline (<FILE_VERIF>);
    close FILE_VERIF;
     
    foreach my $var_tmp (@fic_a_verifier)
    {
    $texte_fic_a_verifier = $texte_fic_a_verifier.$var_tmp
    }
     
    if ($texte_fic_a_verifier =~ /(P[A-Z][A-Z]_Si_.*?\);)/msx )
        {
         print $1."\n";
        }
    J'affiche les résultats dans la console si l'expression est trouvée.

    Or cela ne marche pas, je n'arrive pas à récupérer les 2 patterns, seul un seul s'affiche.
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void PBA_Si_ConvertirCouleur
          (CHAR CouleurIn,
           INT32 CodeCouleur,
           CHAR CouleurOut);
    Auriez-vous une idée ?

    Merci d'avance.

  2. #2
    Mr6
    Mr6 est déconnecté
    Membre éclairé

    Homme Profil pro
    Inscrit en
    Septembre 2004
    Messages
    607
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2004
    Messages : 607
    Points : 794
    Points
    794
    Par défaut
    Il te manque un /g pour récupérer toutes les occurrences

    et eventuellement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $texte_fic_a_verifier = $texte_fic_a_verifier.$var_tmp
    est equivalent à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $texte_fic_a_verifier .= $var_tmp

    @+
    Mr6

  3. #3
    Membre du Club Avatar de philouelgeek
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    60
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 60
    Points : 49
    Points
    49
    Par défaut
    Merci,

    Ca marche

  4. #4
    Membre du Club Avatar de philouelgeek
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    60
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 60
    Points : 49
    Points
    49
    Par défaut
    Par contre il ne m'affiche pas le void avant le Si. le truc c'est que je n'ai pas void à chaque fois, je peut aussi avoir WORD32, BOOLEAN, ....

    Si je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if ($texte_fic_a_verifier =~ /(.*P[A-Z][A-Z]_Si_.*?\);)/msxg )
    Il m'affiche tout le texte présent avant les void

  5. #5
    Membre du Club Avatar de philouelgeek
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    60
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 60
    Points : 49
    Points
    49
    Par défaut
    J'ai essayé en rajoutant :\w mais il ne me prend qu'une seule lettre. Comment faire pour lui indiquer qu'il doit prendre le mot entier ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if ($texte_fic_a_verifier =~ /(\w\sP[A-Z][A-Z]_Si_.*?\);)/msxg )
    donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    d PBA_Si_ConvertirCouleur
          (CHAR CouleurIn,
           INT32 CodeCouleur,
           CHAR CouleurOut);
    d PBA_Si_RecupererCouleur
          (INT32 CodeCouleur,
           CHAR Couleur);

  6. #6
    Mr6
    Mr6 est déconnecté
    Membre éclairé

    Homme Profil pro
    Inscrit en
    Septembre 2004
    Messages
    607
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2004
    Messages : 607
    Points : 794
    Points
    794
    Par défaut
    Soyons brutes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /(\w+\s+P[A-Z][A-Z]_Si_.*?\);)/msxg
    @+
    Mr6

  7. #7
    Membre du Club Avatar de philouelgeek
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    60
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 60
    Points : 49
    Points
    49
    Par défaut
    Cool ça marche, par contre j'ai utilisé pour être moins brute à moins que ce soit pareil

  8. #8
    Membre confirmé
    Avatar de Schmorgluck
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    371
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2006
    Messages : 371
    Points : 558
    Points
    558
    Par défaut
    J'ai l'impression qu'il y a de la complication inutile, là.
    Si j'ai bien compris, il s'agit d'imprimer toutes les lignes contenant "_Si_" et les suivante jusqu'à ce qu'on tombe sur une ligne se terminant par un point-virgule, non ? Si c'est bien le cas, pourquoi ne pas tout simplement utiliser l'opérateur d'étendue ?

    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
     
    ## MODULES
    use strict;
     
    ## VARIABLES
        # Scalaires
    my $fic_a_verifier = "COULEUR.c";
     
    ## PROGRAMME PRINCIPAL
     
    open FILE_VERIF,"<".$fic_a_verifier or die "Impossible d'ouvrir le  fichier $fic_a_verifier !";
     
    while(<FILE_VERIF>)
    {
      print if /_Si_/../;$/;
    }
    Je recommande ce tutoriel pour comprendre le fonctionnement des opérateurs d'étendue en contexte scalaire : Perl Range Operator.
    C'est un peu délicat à manier au début, mais une fois qu'on maîtrise c'est puissant. D'ailleurs, tout le script qui précède peut être réduit à un simple one-liner à taper en ligne de commande :
    perl -lne'print if /_Si_/../;$/' COULEUR.c
    Un petit tuto sur les one-liners : Perl One Liners.

  9. #9
    Mr6
    Mr6 est déconnecté
    Membre éclairé

    Homme Profil pro
    Inscrit en
    Septembre 2004
    Messages
    607
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2004
    Messages : 607
    Points : 794
    Points
    794
    Par défaut
    Je me la note celle-la, je ne l'avais jamais croisé jusqu'à présent, du moins pas présenté dans ce contexte !

    @+
    Mr6

  10. #10
    Membre du Club Avatar de philouelgeek
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    60
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 60
    Points : 49
    Points
    49
    Par défaut
    Cela ne marche pas dans mon cas, car dans le code les _Si_ sont également appelés or ce qui m'intéresse c'est de récupérer uniquement leur déclaration et pas leur appel


    Par exemple j'ai le code suivant :
    Code c : 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
    25
    26
    /****************
     *CONSTANTES
     *****************/
    #define blanc 0
     
    /****************
    *SERVICES INTERNES
    *****************/
    void PBA_Si_ConvertirCouleur
          (CHAR CouleurIn,
           INT32 CodeCouleur,
           CHAR CouleurOut);
     
    /****************
    *SERVICES EXTERNES
    *****************/
    
    PBA_Se_...
    {
    ...
    
    /* Utilisation du _Si_ */ 
    PBA_Si_ConvertirCouleur(Bleu,00120,CouleurSortie);
    ...
    }
    Ce que je souhaite récupérer c'est :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void PBA_Si_ConvertirCouleur
          (CHAR CouleurIn,
           INT32 CodeCouleur,
           CHAR CouleurOut);
    Et pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    PBA_Si_ConvertirCouleur(Bleu,00120,CouleurSortie);
    En tout cas la solution trouvé avec Mr6 marche nickel

    @++


  11. #11
    Mr6
    Mr6 est déconnecté
    Membre éclairé

    Homme Profil pro
    Inscrit en
    Septembre 2004
    Messages
    607
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2004
    Messages : 607
    Points : 794
    Points
    794
    Par défaut
    A mon avis ca marchera si tu précises que tu cherches les fonctions, donc les void
    style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print if /^void.*_Si_/../;$/
    @+
    Mr6

  12. #12
    Membre du Club Avatar de philouelgeek
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    60
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 60
    Points : 49
    Points
    49
    Par défaut
    Mes _Si_ ne commence pas que par des void, il peut aussi y avoir des BOOLEAN, INT, WORD etc ...

    Mais je vais tenter un truc du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    print if /^\w+.*_Si_/../;$/
    ..... Et ça marche, pas mal la solution

    @+

  13. #13
    Membre confirmé
    Avatar de Schmorgluck
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    371
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2006
    Messages : 371
    Points : 558
    Points
    558
    Par défaut
    Attention, ta solution pose un problème : la première regex est trop permissive et va reconnaître, par exemple, un appel de fonction avec récupération dans une variable.
    Ce qui suit sera reconnu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    truc = PBA_Si_ConvertirCouleur(Bleu,00120,CouleurSortie);
    Apparemment ce n'est pas ce que tu veux.

    Donc il faut rendre la première regex plus stricte : elle doit reconnaître un mot situé en début de ligne (et je pense qu'il faut permettre que des caractères blancs le précède), suivi de caractères blancs, suivi d'un mot contenant "_Si_".
    Et puisque c'est du C, il faut probablement prévoir le cas où le premier mot sera suivi de caractères étoile, pour indiquer un retour sous forme de pointeurs.
    Donc, ma suggestion est ce qui suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    print if /^\s*\w+\**\s+\w+_Si_/ .. /;$/;
    Ce qui signifie, pour la première regex : au début de la chaîne, un nombre quelconque d'espaces, suivi d'un mot (au sens Perl) de talle quelconque, suivi d'un nombre quelconque d'étoiles, suivi d'un mot contenant la chaîne "_Si_" (ma version ne peut pas commencer par cette chaîne, mais si ça ne te convient pas, remplace le "+" par un "*").
    Je pense que ça devrait convenir à tes besoins.

  14. #14
    Membre du Club Avatar de philouelgeek
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    60
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 60
    Points : 49
    Points
    49
    Par défaut
    Merci, ça marche niquel

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

Discussions similaires

  1. [RegEx] problème avec les expression régulières
    Par Medmidou dans le forum Langage
    Réponses: 1
    Dernier message: 02/10/2007, 18h35
  2. Problème avec les expression régulière
    Par fouyou dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 04/07/2007, 18h19
  3. [C#] problème avec les expressions régulières
    Par luimême dans le forum C#
    Réponses: 1
    Dernier message: 13/06/2007, 15h44
  4. [VB.net][vs2005] Problème avec les expressions régulières
    Par zouhib dans le forum Windows Forms
    Réponses: 13
    Dernier message: 22/06/2006, 15h56
  5. Problème avec les expressions régulières
    Par Premium dans le forum Collection et Stream
    Réponses: 11
    Dernier message: 18/06/2006, 16h41

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