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 :

Expressions régulières en perl


Sujet :

Langage Perl

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 87
    Points : 46
    Points
    46
    Par défaut Expressions régulières en perl
    Bonjour,

    Première question
    je cherche l'équivalent d'une fonction preg_match_all provenant de php,
    celle ci sauvegarde toutes les occurences d'un motif trouvé dans un tableau.

    Par exemple pour une expression régulière de ce genre :

    /<([a-z])> <br>(.*)<\/br>/

    Dans le tableau d'indice 1 j'ai toute les occurences de ma première parenthèse :
    $tableau[1][0] = a;$tableau[1][0] = c; ... par exemple

    Et dans le tableau d'indice 2 j'ai toutes les occurences de ma deuxième parenthèse. Je cherche à faire cela en perl.

    Deuxième question
    Si je veux que la cible de mon expression régulière soit un gros texte comprennant donc de nombreuses lignes, puis je la faire évaluer comme telle par un moyen simple ou dois je éliminer tout les retour a la ligne avant ?

    Par exemple je récupere le contenu d'un fichier, et au lieu de faire une boucle sur toute les lignes et sur chaque ligne lancer l'expression régulière, je préférerai quelque chose de plus direct me permettant directement de lancer l'expression régulière sur tout le texte.

    Voila c'est tout ... pour le moment.
    Merci d'avance pour vos réponses,
    eric, un débutant dans le monde perl

  2. #2
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    1) preg_match_all() n'a pas d'équivalent direct en Perl, ce que je tendrais à considérer comme une bonne chose, vu qu'il est extrèmement rare de vraiment vouloir exactement le résultat donné par preg_match_all(), je vois deux cas d'utilisation :
    Soit tu as une seule parenthèse capturante dans la regex et tu veux en fait une liste d'un type d'élément, dans ce cas /g en contexte de liste te donne la même chose en Perl :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my @prices = m/\$(\d+\.\d*)/g;
    (preg_match_all renvoie un tableau à deux dimensions ici, alors que tu veux probablement une simple liste...)

    Soit tu en as plusieurs, et dans ce cas soit tu vas faire un post-traitement une seule fois et dans ce cas, autant faire ce traitement tout de suite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    while( m{((<([\w]+)[^>]*>)(.*)(</\3>))}g ) {
      my ($matched, $otag, $text, $ctag) = ($1, $2, $4, $5);
      print <<"EOR";
    matched : $matched
    opening tag : $otag
    content : $text
    closing tag : $ctag
    EOR
    }
    En procédant ainsi, tu as réduit la quantité de code inutile, et tu as gagné un gros avantage en mémoire RAM consommée...

    soit tu vas devoir réutiliser les données plusieurs fois, et faire des traitements complexes et globaux (tris, ...), dans ce cas, il est (très) peu probable que le tableau obtenu avec preg_match_all() ait réellement exactement la structure que tu veux (par exemple tu te contrefous dans la plupart des cas du match complet, seuls les parties t'intéressent, et tu préférerais qu'elles soient organisées, rangées autrement), en Perl tu construiras directement la structure dans ta boucle au lieu de modifier le tableau créé par preg_match_all() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    my @tags;
    while( m{<([\w]+)([^>]*)>(.*)</\1>}g ) {
      my ($tag, $attrs, $text) = ($1, $2, $3);
      push @tags, { tagname => $tag, attributs => $attrs, content => $text };
    }
    En bref preg_match_all() est une fonction qui essaie de faire trop de choses à la fois et fournit des structures par défauts peu judicieuse à mon avis. Les alternatives en Perl sont aussi simples à utiliser et plus claires à mon goût.

    2) Les regexps en Perl peuvent s'appliquer à n'importe quelle chaîne de caractère, qu'elle comporte des retours à la ligne ou pas. Cependant le . ne matche pas les \n par défaut, et ^ et $ correspondent au début et à la fin de la chaîne, plutôt qu'au début et à la fin d'une ligne quelconque de la chaîne. Les modificateurs /m et /s changent ces comportements par défauts. Une astuce importante à garder en tête lorsque l'on fait du matching sur plusieurs lignes c'est qu'il est nettement préférable d'utiliser \s plutôt qu'un simple espace blanc, car \s matche tout type d'espace, y compris les passages à la ligne contrairement à un simple espace, ce qui est fréquemment la sémantique que l'on souhaite.

    --
    Jedaï

    PS : J'ai utilisé dans mes exemples la regexp utilisée dans l'exemple de la doc PHP pour preg_match_all(), ce n'est pas une bonne regexp et je n'en recommande pas l'utilisation pour un problème réel.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 87
    Points : 46
    Points
    46
    Par défaut
    Merci jedai pour cette réponse,

    c'est très clair, cependant je n'arrive désormais pas à faire l'expression régulière en elle meme.

    Voila mon fichier à traiter :
    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
     
    <type>TYPE 1</type>
       <date>DATE 1</date>
            <evenement>EVENEMENT 1</evenement>
            <evenement>EVENEMENT 2</evenement>
            ...
     
       <date>DATE 2</date>
            <evenement>EVENEMENT 3</evenement>
            <evenement>EVENEMENT 4</evenement>
            ...
     
    <type>TYPE 2</type>
       <date>DATE 1</date>
            <evenement>EVENEMENT 5</evenement>
            <evenement>EVENEMENT 6</evenement>
            ...
    Ce fichier n'est pas un xml mais du html. Voila j'aimerai donc récupérer dans une liste de hash la liste des évenements avec la date et le type associé a chacun d'eux.

    J'ai pensé à quelque chose du genre :

    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
     
     
    my $i = 0;
    my @evenements;
    my $type,$date,$evenement;
     
    while( /<type>(.*)<\/type>/g ) 
    {
      $type = $1;
     
      while( /<date>(.*)<\/date>/g ) 
      {
        $date = $1;
     
        while( /<evenement>(.*)<\/evenement>/g ) 
        {
          $evenement = $1;
          push @{$evenements[$i]}, { nomevenement => $evenement, date => $date, type => $type };
          $i ++;
        }
      }
    }
    }
    Je ne suis pas sur ma machine, donc je n'ai pas pu tester ce code, mais je n'ai rien de mieux qui me vient à l'esprit, je me doute qu'il doit avoir une seule expression régulière qui permet de simplifier tout ca et d'éliminer ces trois boucles, mais laquelle ?

    Si quelqu'un à la solution, merci à lui encore.

Discussions similaires

  1. Réponses: 3
    Dernier message: 15/07/2014, 04h45
  2. expression régulière en perl
    Par amibar dans le forum Langage
    Réponses: 3
    Dernier message: 14/07/2012, 13h14
  3. expression régulière en perl
    Par samordi dans le forum Langage
    Réponses: 6
    Dernier message: 17/10/2011, 21h45
  4. Expression Régulière PERL
    Par slyv dans le forum Langage
    Réponses: 8
    Dernier message: 25/10/2005, 21h30

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