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 :

extraction de 2 mots consécutifs


Sujet :

Langage Perl

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 77
    Par défaut extraction de 2 mots consécutifs
    Bonjour à tous c'est encore moi, la novice en perl qui en apprend un peu plus chaque jour grâce à ce forum.
    Aujourd'hui je cherche à faire un programme qui extrait tous les bigrammes d'un texte avec la fréquence de chaque.

    output :

    'le lapin' => 2
    'lapin mange' => 1
    ...

    J'ai déjà un bout de code mais j'ai encore un problème avec ces foutus variable ;-) le voici :

    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
     
    #! /usr/bin/perl
    use warnings;
    use strict;
     
    my $fichier_corpus = 'input.txt';
    my $fichier_fr = 'output.txt';
    open my $fh_corpus, "<:utf8", $fichier_corpus or die "Impossible de lire $fichier_corpus\n";
    open my $fh_fr , ">>:utf8", $fichier_fr or die "Impossible de lire $fichier_fr\n";
    my %words;
    my $ligne = <$fh_corpus>;
     
    while (my $ligne =~ /(\w+ (\w+))/g) {
      ++$words{$1};
      pos($ligne) = $-[2];
    }
     
    for (sort { index($ligne,$a) <=> index($ligne,$b) } keys %words) {
      print {$fh_fr}"'$_' => $words{$_}\n";
    }
    quand je l'execute il m'affiche : "use of uninitialized value $ligne in pattern match (m//) at ..."

    Quelle modif dois-je apporter ?

    Merci beaucoup d'avance de votre aide.

  2. #2
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2011
    Messages
    184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 184
    Par défaut
    Tu déclares deux fois la variables $ligne. Enlève le my dans le while.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 77
    Par défaut
    Merci Dimitry ! ça va tout de suite mieux. Par contre il ne traite que la première ligne de mon fichier

  4. #4
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2011
    Messages
    184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 184
    Par défaut
    L'opérateur diamant (le <>) permet de lire ligne par ligne. Il faut donc boucler :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    while(defined(my $ligne = <$fh_corpus>)) {
      if ($ligne =~ /(\w+ (\w+))/g) {
      ...
      }
    }

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 77
    Par défaut
    j'ai fait la modif mais là il ne traite que le premier bigramme de la ligne.

  6. #6
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2011
    Messages
    184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 184
    Par défaut
    A quoi ressemblent tes lignes ?

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 77
    Par défaut
    à un texte par ligne.

    exemple :
    Les lapins sont crétin.
    Ils sont fous ces romains.
    ...

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 77
    Par défaut
    J'ai regardé plus en détails ma sortie et je n'ai pas exactement ce que j'aimerai voilà mon entrée :
    un fichier texte de type :

    texte +ref \n
    texte +ref \n
    ...

    La crise nucléaire s'est aggravée mardi au Japon après une nouvelle explosion et un incendie à la centrale de Fukushima-Dai-Ichi, où les accidents se succèdent depuis le séisme de vendredi qui a fait offciellement 3 373 morts et de milliers de disparus. B61M
    L'agence de presse Kyodo a fait savoir qu'elle organisait des va-et-vient entre les équipes de la salle de contrôle de la tranche n°4 car la radioactivité y est devenue trop élevée pour que les ingénieurs y fassent un travail normal. B56F
    ...
    pour synthétiser j'ai : w=mot

    w1 w2 w3 w4. w5 w6. +ref
    w7 w8 w9. w10 w11 w13 w14. +ref

    et j'essaye d'avoir les bigrammes d'une ligne plus la ref :

    'w1 w2', 'w2 w3', 'w3 w4'... +ref
    'w7 w8', 'w8 w9'... +ref

  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 : 60
    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
    Par défaut
    Tout d'abord, plutôt que de tenter de matcher des bigrammes avec la regexp /(\w+ (\w+))/g, je séparerais les mots (avec split et un séparateur /\W/ ou plus précis, ou bien avec une regexp /(\w+)/g). Ensuite seulement, je construirais les bigrammes.
    Par ailleurs, et en préliminaire, j'extraierais de la ligne la référence de fin de ligne (dont il faudrait fournir le format général afin d'établir une regexp pour lui).

    Enfin, je note dans le texte que les nombres > 1000 sont écrit avec un séparateur de milliers. Ceci générera donc deux mots. Il y a peut-être d'autres subtilités de typographie de ce style.

  10. #10
    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 : 60
    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
    Par défaut
    Exemple d'algorithme :

    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
    foreach (<DATA>) {
      my ($text, $ref) = /(.*?)(\w\d\d\w)$/;
     
      my @words;
      while ($text =~ /(\w+)/g) {
        my ($word) = $1;
        push @words, [ $word => pos($text) ];
      }
      foreach my $index (0 .. $#words-1) {
        print "{$words[$index]->[0] $words[$index+1]->[0]} => ", $words[$index]->[1], ", ";
      }
      print " + $ref\n";
    }
     
    __DATA__
    les chats sont gris M45R

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 77
    Par défaut
    Merci Philou mais j'ai encore et toujours le même problème de variable :

    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
     
    #! /usr/bin/perl
    use warnings;
    use strict;
     
    my $fichier_corpus = 'input.txt';
    my $fichier_fr = 'output.txt';
    open my $fh_corpus, "<:utf8", $fichier_corpus or die "Impossible de lire $fichier_corpus\n";
    open my $fh_fr , ">>:utf8", $fichier_fr or die "Impossible de lire $fichier_fr\n";
    my $ligne = <fh_corpus>;
     
    foreach ($ligne) {
      my ($text, $ref) = /(.*?)(\w\d\d\w)$/;
     
      my @words;
      while ($text =~ /(\w+)/g) {
        my ($word) = $1;
        push @words, [ $word => pos($text) ];
      }
      foreach my $index (0 .. $#words-1) {
        print "{$words[$index]->[0] $words[$index+1]->[0]} => ", $words[$index]->[1], ", ";
      }
      print " + $ref\n";
    }

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 77
    Par défaut
    j'ai corrigé mon code pour finir avec ç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
    16
    17
    18
    19
    20
    21
    22
    23
     
    #! /usr/bin/perl
    use warnings;
    use strict;
     
    my $fichier_corpus = 'input.txt';
    my $fichier_fr = 'output.txt';
    open my $fh_corpus, "<:utf8", $fichier_corpus or die "Impossible de lire $fichier_corpus\n";
    open my $fh_fr , ">>:utf8", $fichier_fr or die "Impossible de lire $fichier_fr\n";
    my $ligne = <$fh_corpus>;
     
    foreach ($ligne) {
      my ($text, $ref) = /(.*?)(\d+)$/;
      my @words;
      while ($text =~ /(\w+)/g) {
        my ($word) = $1;
        push @words, [ $word => pos($text) ];
      }
      foreach my $index (0 .. $#words-1) {
        print {$fh_fr}"{$words[$index]->[0] $words[$index+1]->[0]}, ";
      }
      print {$fh_fr} " + $ref\n";
    }
    Mais à la sortie, il continue à ne traiter que la première ligne du fichier.

  13. #13
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2011
    Messages
    184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 184
    Par défaut
    Même problème que précédemment :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    foreach ($ligne) {
    Devrait être :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    while(defined(my $ligne = <$fh_corpus>)) {
    Non, je n'utiliserai pas foreach pour parcourir un tableau.

  14. #14
    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 : 60
    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
    Par défaut
    Citation Envoyé par Dimitry.e Voir le message
    Non, je n'utiliserai pas foreach pour parcourir un tableau.
    Je suis d'accord (même si j'ai utilisé foreach dans mon exemple simplissime).

    Je vois au moins deux raisons à cela :
    - le fichier n'est pas préalablement lu en mémoire en totalité (ce qui peut être problématique en cas de gros fichier d'entrée)
    - le numéro de ligne courant ($.) contient le numéro de la ligne en cours de traitement dans la boucle, contrairement à l'usage de foreach, pour lequel il vaut le dernier numéro de ligne (puisque le fichier a déjà été totalement lu lors du traitement de la première ligne).

  15. #15
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 77
    Par défaut
    Pour information mon fichier_corpus fait 48ko.

  16. #16
    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 : 60
    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
    Par défaut
    Comment dire, tu n'as pas de variable $class, mais peut-être veux-tu parler de $ref ?
    A priori, ça viendrait de l'expression régulière qui sépare le texte de la référence. Comment déjà demandé dans mon premier post, tu n'as toujours pas fourni le format de cette référence. Du coup, impossible de valider l'expression régulière Par ailleurs, si tu souhaites que l'on avance sur ton problème, fournis nous ton fichier d'entrée, ou au moins, un extrait représentatif.

  17. #17
    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 : 60
    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
    Par défaut
    Tu dois mettre ton fichier en pièce jointe (ou hébergés sur un hébergeur de fichier), car les retours à la ligne ont une importance CAPITALE pour ton analyse. Dans la citation, on ne sait pas où ils sont placés.

    Par ailleurs, tu n'as toujours pas indiqué comment était composé une référence...

  18. #18
    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 : 60
    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
    Par défaut
    Ton fichier ne semble pas être en UTF8 mais en latin-1. Par ailleurs, il est au format texte windows (chaque ligne se termine par \r\n). Enfin, l'expression régulière pour extraire $text et $ref (ou $class) ne fait pas référence à $ligne.

    Voici un script qui corrige tous ces problèmes.
    Par ailleurs, le résultat ne donne pas la position des bigrammes. Ceci est-il demandé ?

    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
    #! /usr/bin/perl
    use warnings;
    use strict;
     
    use Encode;
     
    my $fichier_corpus = shift @ARGV;
    my $fichier_fr = $fichier_corpus.".gram.txt";
    open my $fh_corpus, "<:encoding(latin-1)", $fichier_corpus or die "Impossible de lire $fichier_corpus\n";
    open my $fh_fr , ">>:utf8", $fichier_fr or die "Impossible de lire $fichier_fr\n";
     
    while (defined(my $ligne = <$fh_corpus>)) {
      $ligne = encode("utf8", $ligne);
      my ($text, $ref) = $ligne =~ /(.*?)(A61K\d+)\s*$/;
      my @words;
      while ($text =~ /(\w+)/g) {
        my ($word) = $1;
        push @words, [ $word => pos($text) ];
      }
      foreach my $index (0 .. $#words-1) {
        print {$fh_fr}"{$words[$index]->[0] $words[$index+1]->[0]}, ";
      }
      print {$fh_fr} " + $ref\n";
    }

  19. #19
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    77
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 77
    Par défaut
    Merci Philou67430 pour ton aide, oui j'avais oublié de dire que la position des bigrammes n'était pas importante et evidemment par maladresse j'ai envoyé l'extrait qui n'était pas encodé en utf8.
    Sinon tout fonctionne très bien et fait exactement ce que je souhaitais !

    Un grand merci à toute l'équipe et sûrement à bientôt ;-)

  20. #20
    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 : 60
    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
    Par défaut
    N'oublie pas le tag résolu

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 5
    Dernier message: 30/06/2015, 11h01
  2. [XL-2007] extraction 1er/dernier mot d'une cellule
    Par cedinfo17 dans le forum Excel
    Réponses: 4
    Dernier message: 28/08/2011, 04h07
  3. extraction d'un mot d'une chaine
    Par manren dans le forum Shell et commandes GNU
    Réponses: 7
    Dernier message: 18/10/2010, 23h57
  4. ListBox - Extraction d'un mot
    Par Bouillon dans le forum Delphi
    Réponses: 2
    Dernier message: 30/09/2006, 23h46
  5. [RegEx] Extraction d'un mot et d'un nombre dans
    Par lodan dans le forum Langage
    Réponses: 9
    Dernier message: 20/09/2006, 21h23

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