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 :

Regexp: extraire du texte entre deux balises


Sujet :

Langage Perl

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

    Informations forums :
    Inscription : Octobre 2006
    Messages : 43
    Points : 26
    Points
    26
    Par défaut Regexp: extraire du texte entre deux balises
    Bonjour,
    Je viens chercher un peu d'aide pour la création d'une regexp.
    Je suis entrain de faire un script qui execute la commande :
    grep <balise> file.xml | sort | uniq -c

    je récupère le résultat de la commande et je dois traiter chacune de ces lignes.
    Chaque ligne de résultat se présente comme cela:
    54 <balise>fashion/Femme/accessoires</balise>

    Il faut que je récupère le contenu entre <balise></balise>
    et que je récupère uniquement 'fashion' sachant que dans certains cas il y a qu'un seul mot entre <balise></balise> (il aurait pu y avoir <balise>fashion</balise>.

    Je pense que cela est faisable avec une regexp mais je n'ai pas trouvé encore ce qu'il me faut...

    Merci d'avance pour votre aide.

  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
    Et bien j'aurais sans doute fais l'intégralité du processus en Perl, mais si tu as commencé comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    grep <balise> file.xml | sort | uniq -c | perl -pe 's{.*<balise>([^</]+)(/[^<]*)?</balise.*}{$1};'
    NB : Manipuler du XML avec des regexp est toujours fragile et peu sûr... Il vaut mieux de loin utiliser un vrai parser XML.

    --
    Jedaï

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

    Informations forums :
    Inscription : Octobre 2006
    Messages : 43
    Points : 26
    Points
    26
    Par défaut
    J'ai fais le process dans un script perl, voici le début de mon traitement :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    while(defined(my $filename = glob("*.xml"))){
     
            my @cat = `grep balise $path/file.xml | sort | uniq -c`;
     
            my $i = 0;
            while($cat[$i] ne ""){
                    #delete spaces
                    $cat[$i] =~ s/\s+//g;
     
                    #recuperation du nom de la categorie, premier mot entre <balise></balise>
                    #pour chacune de ces cat, recuperer le nombre du compteur affiché juste avant la chaine "<balise>"
            }
    }
    J'ai quand même essayé avec la ligne que tu m'as donnée mais ca ne marche pas...

  4. #4
    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
    Citation Envoyé par moook
    J'ai quand même essayé avec la ligne que tu m'as donnée mais ca ne marche pas...
    La ligne que je t'ai donné, c'était à utiliser directement en ligne de commande : c'est ce qu'on appelle un uniligne (oneliner) Perl, où l'on utilise Perl directement en ligne de commande.
    Si je voulais faire l'intégralité en Perl, j'utiliserais plutôt XML::Twig.

    Si tu tapes direct en ligne de commande :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    grep <balise> file.xml | sort | uniq -c | perl -pe 's{.*<balise[^>]*>([^</]+)(/[^<]*)?</balise.*}{$1};'
    Ca marchera, j'ai testé (du moins si ton XML ressemble à ce que tu as écris).

    --
    Jedaï

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 43
    Points : 26
    Points
    26
    Par défaut
    C'est en ligne de commande que j'ai exécuté cette ligne.
    il me dit :
    bash: balise: No such file or directory

    Pour le module xml, je ne peux pas installer de modules sur ma machine du coup je dois me débrouiller autrement.

  6. #6
    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
    Oh.. D'accord, l'erreur vient du grep, j'ai juste recopié ce que tu avais marqué dans ton premier post, mais en fait les <> étaient de trop :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    grep '<balise' file.xml | sort | uniq -c | perl -pe 's{.*<balise[^>]*>([^</]+)(/[^<]*)?</balise.*}{$1};'
    --
    Jedaï

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 43
    Points : 26
    Points
    26
    Par défaut
    En effet c'est beaucoup mieux et c'est ce résultat qu'il me faut, j'essaye de l'adapter pour mon script mais je galère

    Est ce que tu peux me donner quelques pistes pour faire la même regexp mais dans mon script?

    Merci

  8. #8
    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
    Pourquoi -c dans uniq ? Tu supprimes le compte des occurences dans la regex suivante de tout façon...
    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 strict; use warnings;
     
    my @lines;
    while( <> ) {
      push @lines, $1 if m{<balise[^>]*>([^</]+)(/[^<]*)?</balise};
    }
    @lines = uniq(sort @lines);
     
    sub uniq {
      no warnings "uninitialized";
      my $prec;
      grep {my $result = ($prec ne $_); $prec = $_; $result} @_;
    }
    __END__
    --
    Jedaï

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 43
    Points : 26
    Points
    26
    Par défaut
    le -c me permet de compter le nombre de fois ou il trouve une catégorie dans le fichier xml .
    ça me donne quelque chose comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
         54                 <cat>fashion/Femme/accessoires</cat>
        924                 <cat>fashion/Femme/accessoires/sacs</cat>
        2684                 <cat>fashion/Femme/chaussures</cat>
        253                   <cat>auto/berline</cat>
        520                   <cat>cuisine/ustensiles</cat>
        520                   <cat>hightech</cat>
    moi je veux uniquement garder les catégories mères et comptabiliser le nb de résultat (je dois récup le compteur, d'ou le -c mais je ne procède peut etre pas correctement...). aprés le traitement il faut que j'ai quelque chose comme ça :

    fashion: 3658 (54+924+2684)
    auto : 253
    cuisine: 520 ........

    Dans certains cas, il y a une seule catégorie dans mon <cat></cat>
    et donc par forcement de séparateur "/"

  10. #10
    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
    Je vois, donc tu veux te servir du compte, ce n'était pas le cas dans la ligne que je t'ai donnée (et tu ne l'as pas demandé non-plus...).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #! /usr/bin/perl
    use strict; use warnings;
     
    my @lines;
    while( <> ) {
      push @lines, $1 if m{<cat[^>]*>([^</]+)(/[^<]*)?</cat};
    }
    my %cats;
    map { $cats{$_}++ } @lines;
     
    for my $cat ( sort keys %cats ) {
      print "$cat : $cats{$cat}\n";
    }
    __END__
    --
    Jedaï

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 43
    Points : 26
    Points
    26
    Par défaut
    ok, merci pour ta réponse,
    Il faut que je parse plusieurs fichiers "*.xml"

    J'ai essayé comme ceci mais ça ne fonctionne pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    $path = "...";
    while(defined(my $filename = glob("$path*.xml"))){
           my @lines = `grep catkk $filename| sort | uniq -c`;
     
           [traitement que tu m'a donné]

  12. #12
    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
    Le dernier code que je t'ai donné fait l'intégralité du travail, il suffit de lui passer en paramètre le nom du fichier que tu veux traiter. Et de le mettre dans une boucle si tu dois traiter plusieurs fichiers.

    --
    Jedaï

Discussions similaires

  1. [RegExp] Extraire le texte entre 2 balises
    Par d1g-2-d1g dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 27/02/2007, 19h15
  2. [DOM] [Débutant] Récupérer texte entre deux balises
    Par webrider dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 27/02/2007, 09h49
  3. Réponses: 24
    Dernier message: 20/08/2006, 14h08
  4. supprimer texte entre deux balises specifiques
    Par HurtMarley dans le forum Langage
    Réponses: 2
    Dernier message: 31/01/2006, 18h30

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