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 :

PHP PERL et regex


Sujet :

Langage Perl

  1. #1
    Membre régulier Avatar de floanne
    Inscrit en
    Février 2006
    Messages
    167
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Février 2006
    Messages : 167
    Points : 78
    Points
    78
    Par défaut PHP PERL et regex
    Bonjour;

    j'avais écrit cette regex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    m/((?:^\s*CARD\s+\d+\s+ALARM\s+STATUS.*$\n(?:^.*$\n){2})*)/m
    Pour matcher un truc dans ce genre (dans un log)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        CARD 1217 ALARM STATUS = No Alarms.
          DSM PORT A:      ALARM STATUS       = No Alarms.
          DSM PORT B:      ALARM STATUS       = No Alarms.
        CARD 1317 ALARM STATUS = No Alarms.
          DSM PORT A:      ALARM STATUS       = No Alarms.
          DSM PORT B:      ALARM STATUS       = No Alarms.
    Sur le site http://lumadis.be/regex/test_regex.php
    ça marche très bien, mais dans mon script Perl ça ne marche pas du tout.

    J'ai donc écrit une autre regex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    m/^((?:\s*CARD\s+\d+\s+ALARM\s+STATUS.*\n.*\n.*\n)+)/m
    Qui elle marche...

    J'ai donc résolu mon problème... Mais sans comprendre pourquoi

    Si quelqu'un pouvait m'expliquer... J'ai horeur de programmer "au hazar"...

    ++Florent.

  2. #2
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    Salut,

    C'est quoi le but du jeu, que veux-tu capturer ?
    • Avant de poser une question, n'hésitez pas à chercher dans la FAQ et les forums
    • Merci d'utiliser les balises de code (# dans l'éditeur)
    • N'oubliez pas de vous servir des boutons , et

    S.N.A.F.U

  3. #3
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    En attendant de savoir si cela correspond à ton besoin, j'ai simplifié la regex, mais je ne sais pas si c'est ce que tu cherches à obtenir.

    Code perl : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    #!/usr/bin/perl
    use warnings;
     
    $str = "CARD 1217 ALARM STATUS = No Alarms.
          DSM PORT A:      ALARM STATUS       = No Alarms.
          DSM PORT B:      ALARM STATUS       = No Alarms.
        CARD 1317 ALARM STATUS = No Alarms.
          DSM PORT A:      ALARM STATUS       = No Alarms.
          DSM PORT B:      ALARM STATUS       = No Alarms.";
     
    while ( $str =~ m/\s* ( CARD \s+ \d+ \s+ ALARM \s+ STATUS .* )/gx ) {
     
        print "$1\n";
    }

    => et déplaçons-nous chez les mongueurs...
    • Avant de poser une question, n'hésitez pas à chercher dans la FAQ et les forums
    • Merci d'utiliser les balises de code (# dans l'éditeur)
    • N'oubliez pas de vous servir des boutons , et

    S.N.A.F.U

  4. #4
    Membre régulier Avatar de floanne
    Inscrit en
    Février 2006
    Messages
    167
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Février 2006
    Messages : 167
    Points : 78
    Points
    78
    Par défaut
    Le but du jeu est de capturer tout l'extrait en une seul fois (sachant qu'il y a d'autre info avant et après le bloc que j'ai posté evidemment). Ma 2eme regex marche très bien mais je comprends pas pourquoi la première ne donne pas le même résultat...

    Le but de ma question est de comprendre, pas de faire un truc qui marche

    Merci de ta réponse.
    ++Florent.

  5. #5
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    Mais elle marche comment ?
    Parce que ceci par exemple ne me donne que le premier bloc :

    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
    use warnings;
     
    $str = "CARD 1217 ALARM STATUS = No Alarms.
          DSM PORT A:      ALARM STATUS       = No Alarms.
          DSM PORT B:      ALARM STATUS       = No Alarms.
        CARD 1317 ALARM STATUS = No Alarms.
          DSM PORT A:      ALARM STATUS       = No Alarms.
          DSM PORT B:      ALARM STATUS       = No Alarms.";
     
    $str =~ m/^((?:\s*CARD\s+\d+\s+ALARM\s+STATUS.*\n.*\n.*\n)+)/m;
     
    print $1;
    --- edit ---
    J'ai les deux blocs si j'utilise une autre chaîne :
    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
    #!/usr/bin/perl
    use warnings;
     
    $str = "contenu avant
    CARD 1217 ALARM STATUS = No Alarms.
          DSM PORT A:      ALARM STATUS       = No Alarms.
          DSM PORT B:      ALARM STATUS       = No Alarms.
        CARD 1317 ALARM STATUS = No Alarms.
          DSM PORT A:      ALARM STATUS       = No Alarms.
          DSM PORT B:      ALARM STATUS       = No Alarms.
    contenu après";
     
    $str =~ m/^((?:\s*CARD\s+\d+\s+ALARM\s+STATUS.*\n.*\n.*\n)+)/m;
     
    print $1;
    • Avant de poser une question, n'hésitez pas à chercher dans la FAQ et les forums
    • Merci d'utiliser les balises de code (# dans l'éditeur)
    • N'oubliez pas de vous servir des boutons , et

    S.N.A.F.U

  6. #6
    Membre régulier Avatar de floanne
    Inscrit en
    Février 2006
    Messages
    167
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Février 2006
    Messages : 167
    Points : 78
    Points
    78
    Par défaut
    C'est à cause du dernier \n, ajoute un saut de ligne à la fin de la chaine et tout sera maché.

    Merci pour ta réponse ultra rapide.

    ++Florent.

  7. #7
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    Au passage :
    $/ est le séparateur d'enregistrements en entrée. Par défaut, $/ est un saut de ligne. Cette variable modifie l'idée que Perl se fait de ce qu'est une ligne, en particulier avec l'opérateur <> (parfois appelé readline() ).
    => problème dans le premier motif...
    • Avant de poser une question, n'hésitez pas à chercher dans la FAQ et les forums
    • Merci d'utiliser les balises de code (# dans l'éditeur)
    • N'oubliez pas de vous servir des boutons , et

    S.N.A.F.U

  8. #8
    Membre expert
    Avatar de s.n.a.f.u
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2006
    Messages
    2 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Août 2006
    Messages : 2 760
    Points : 3 545
    Points
    3 545
    Par défaut
    En faisant un peu respirer la regex, ça passe mieux :
    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
    #!/usr/bin/perl
    use warnings;
     
    my $str = "contenu avant
        CARD 1217 ALARM STATUS = No Alarms.
          DSM PORT A:      ALARM STATUS       = No Alarms.
          DSM PORT B:      ALARM STATUS       = No Alarms.
        CARD 1317 ALARM STATUS = No Alarms.
          DSM PORT A:      ALARM STATUS       = No Alarms.
          DSM PORT B:      ALARM STATUS       = No Alarms.
    contenu après";
     
    $str =~ m/( (?:^\s* CARD \s+ \d+ \s+ ALARM \s+ STATUS .*$ \n (?:^.*$ \n){2} )+ )/mx;
     
    print $1;
    • Avant de poser une question, n'hésitez pas à chercher dans la FAQ et les forums
    • Merci d'utiliser les balises de code (# dans l'éditeur)
    • N'oubliez pas de vous servir des boutons , et

    S.N.A.F.U

  9. #9
    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 : 58
    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
    Points : 5 753
    Points
    5 753
    Par défaut
    Je n'ai pas d'explication raisonnable, mais une piste pour comprendre serait de considérer l'expression régulière suivante, qui elle, fonctionne à peu près comme tu le souhaiterais :
    m/((?:^\s*CARD\s+\d+\s+ALARM\s+STATUS.*$(?:\n^.*$){2})+\n)/m

    Edit : S.n.a.f.u a trouvé mieux...
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

Discussions similaires

  1. [JBoss Portal] Portlet Bridge PHP, Perl, Java
    Par green_rabbit dans le forum Portails
    Réponses: 1
    Dernier message: 17/11/2008, 12h36
  2. passage de paramètres php-perl
    Par danFr dans le forum Langage
    Réponses: 1
    Dernier message: 26/10/2008, 21h06
  3. Réponses: 7
    Dernier message: 23/04/2006, 01h38
  4. Réponses: 11
    Dernier message: 22/02/2006, 17h25

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