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

Python Discussion :

compter le nombre de meme mot dans un .txt


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Avril 2009
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 20
    Par défaut Recuperer des donnees depuis un .txt
    3/4 questions resolu
    02 mai 2009 A suivre, ICI
    Python V3

    Bonjour tout le monde, (Je met a jour ce post pour que ce soit plus simple)

    Je suis debutant en programmation, c'est avec un amis que je decouvre le language "Python".
    Je souhaiterais recuperer des donnees depuis un fichier .txt

    1) Le nom de la "target".
    (dans ce cas c'est "Longhorn Krond the Unliving" mais ca peut etre "an Undead")
    La target : Longhorn Krond the Unliving

    2) Si "Guzzlerobeer" apparait dans le texte, le citer [FONCTIONE]
    Guzzlerobeer : vous a "heal" durant ce combat

    3) Le nombre de fois que Guzzlerobeer me "heal" [FONCTIONE]
    (en locurence, une fois dans ce log)
    Nombre de fois que Guzzlerobeer vous a "heal" : 1

    4) Cummuler toutes sorte de valeurs et les classer [FONCTIONE]

    On vous a heal pour : 3000 points


    Fichier Texte type :
    Longhorn Krond the Unliving has been awakened by Tallaared.
    [Mon Dec 01 22:51:07 2008] Your target is too far away, get closer!
    [Mon Dec 01 22:51:08 2008] Boldak's holy blade cleanses his target!(20696)
    [Mon Dec 01 22:51:08 2008] Your target is too far away, get closer!
    [Mon Dec 01 22:51:10 2008] You crush Longhorn Krond the Unliving for 236 points of damage.
    [Mon Dec 01 22:51:11 2008] You cannot see your target.
    [Mon Dec 01 22:51:13 2008] Gogad hit Longhorn Krond the Unliving for 176 points of non-melee damage.
    [Mon Dec 01 22:51:17 2008] Gogad`s pet slashes Longhorn Krond the Unliving for 107 points of damage.
    [Mon Dec 01 22:51:18 2008] The pounding hooves deafen you. You have taken 3520 points of damage.
    [Mon Dec 01 22:51:19 2008] a jester of bristlebane says 'How's the weather up there?'
    [Mon Dec 01 22:51:19 2008] Gogad scores a critical hit! (244)
    [Mon Dec 01 22:51:33 2008] Your Focused Paragon of Spirit spell has worn off of Hotdamm.
    [Mon Dec 01 22:51:35 2008] The stomping echoes fade away.
    [Mon Dec 01 22:52:04 2008] Your Belt of Contempt feels alive with power.
    [Mon Dec 01 22:52:26 2008] Guzzlerobeer has healed you for 1000 points.
    [Mon Dec 01 22:52:32 2008] Pierro has healed you for 2000 points.
    [Mon Dec 01 22:52:39 2008] Your Runed Diamond flickers with a pale light.
    [Mon Dec 01 22:52:39 2008] Your Spiritcaller Totem of the Feral feels alive with power.
    [Mon Dec 01 22:53:57 2008] You gained raid experience!
    [Mon Dec 01 22:53:57 2008] Longhorn Krond the Unliving's corpse falls.
    Voici ou j'en suis dans mon Code Python :
    Ce qui fonctionne uniquement
    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
    31
    32
    33
    34
    35
    36
    37
    38
     
    import re
     
    def foo (fichier):
    	z = open(fichier, 'r')
    	s = 0
    	somme1 = 0
    	somme2 = 0
     
    	for ligne in z:
    		ligne = ligne[:-1]
    		a = re.search('Guzzlerobeer',ligne)
    		d = a
     
    		c = re.findall('Guzzlerobeer',ligne)
    		s = s + len(c)
     
    		p1 = re.compile('(?P<nombre>[0-9]+) points of damage')
    		n = p1.search(ligne)
     
    		p2 = re.compile('(?P<nombre>[0-9]+) points of non-melee damage')
    		m = p2.search(ligne)
     
    		if n:
    			str_nc = n.group('nombre')
    			somme1 = somme1 + int(str_nc)
    		if m:
    			str_nb = m.group('nombre')
    			somme2 = somme2 + int(str_nb)
    		if a:
    			Guzzlerobeer = a
     
     
    	print ("Le mot recherche est :", Guzzlerobeer.group())
    	print ("Le nombre de fois que ce mot apparait est :", s)
    	print ("total points of damage : ", somme1)
    	print ("total points non-melee of damage : ", somme2)
    	z.close()

    Voila, si vous avez d'autres indices SVP
    Merci.

  2. #2
    Membre émérite
    Homme Profil pro
    Inscrit en
    Janvier 2006
    Messages
    491
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Corse (Corse)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 491
    Par défaut
    bonjour pour trouver un mot dans une chaine il existe une fonction find qui te donne la position du mot dans la chaine
    ou retourne 0 si le mot n'y est pas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    for ligne  in z:
     
        if ligne.find("monstre")>0:
     
            compteur+=1
     
    print compteur
    si tu tiens à utiliser les expressions rationnelles
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    for ligne  in z:
        reg=re.compile('^.+monstre')
        if reg.match(ligne):
     
            compteur+=1
     
    print compteur

  3. #3
    Membre émérite
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Par défaut
    Je n'ai pas testé ton code par manque de temps, mais il me semble que ton premier regex manque d'un + après la classe de caractères.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (?P<text>[a-zA-Z0-9_]+)
    Le code suivant ne fera jamais rien, puisqu'une ligne vide sera la chaîne "\n" et qu'une fois la fin de fichier atteinte, la boucle sortira d'elle même. A mon sens, tu peux la retirer.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if ligne == "":
        break
    Dernière petite remarque, tu initialises mot à zero, alors qu'il va contenir du texte. Préfère le mettre à None ou une châine vide.


    Petites corrections aux deux algorithmes d'au dessus:
    Le premier ne compterait qu'une seule occurence de "monstre" par ligne. Dans notre cas c'est suffisant, mais si le mot peut apparaitre deux fois, préfère cette boucle:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> for line in z:
    ...     pos = line.find("monstre")
    ... 
    ...     while pos > 0:
    ...         count += 1
    ...         pos = l.find("monstre")
    Et pour matcher avec une regex
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> ligne = "Bienvenue chew monstre &co, des monstres pour effrayer les gosses"
    >>> import re
    >>> pattern = re.compile("monstre")
    >>> pattern.search(ligne)
    <_sre.SRE_Match object at 0xb7cfb528>

  4. #4
    Membre éprouvé

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Par défaut
    Une méthode courte sans regex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #!/usr/bin/env python
    #coding=utf-8
    texte ="""Bienvenue chez monstre & co.,
    des monstres pour effrayer les sales gosses
    mais aussi des gentils monstres pour les gentils gosses."""
     
    print len(texte.split('monstre')) - 1

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    Bienvenue sur le forum,

    L'utilisation de regex pour ce problème est à mon sens inadaptée, du moins si vous cherchez à compter un mot que vous connaissez a priori, ce qui est ce qu'on comprend à partir du titre de votre post mais qui n'est pas ce que vous faites dans le code.
    Mais je suppose que vous le savez et que vous voulez simplement vous entrainer sur les expressions régulières.

    1 -
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if ligne == "":
        break
    peut être enlevé
    L'instruction for ligne in z:
    se débrouille très bien pour s'apercevoir en bout de fichier qu'il n'y a plus de ligne.

    2 - Il faut rajouter un "+' après l'ensemble [a-zA-Z0-9_].

    3 - La fonction foo() est définie, mais il faudrait une instruction pour l'appeler.....

    4 - Tel qu'est écrit votre code, vous ne recherchez pas le nombre d'occurences de "monstre" mais vous affichez le mot se trouvant après la dernière expression 'Jean tue le ' trouvée dans le texte

    5 - Parallèlement , et sans rapport, vous faites la somme de tous les nombres rencontrés dans le texte

    Ces deux points sont illustrés par le code suivant

    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
    31
    32
    33
    34
    35
    import re
     
    texte = """Jean est un super hero
    Jean tue le monstre n1
    Jean tue le monstre n2
    Juju tue les 38 fourmis
    Le petit Cedric tue le monstre aussi
    Pierre-Jean tue le temps en jouant avec des allumettes
    Et la Maman a un monstre de boulot"""
     
    def foo (t):
        #z = open(fichier, 'r')
        z = t.splitlines(True)
        mot = 0
        result = 0
     
        for ligne in z:
            ligne = ligne[:-1]
            p1 = re.compile('Jean tue le (?P<text>[a-zA-Z0-9_]+)')
            a = p1.search(ligne)
            p2 = re.compile('(?P<nombre>[0-9]+)')
            b = p2.search(ligne)
     
            if a:
                mot = a.group('text')
            if b:
                str_nb = b.group('nombre')
                result = result + int(str_nb)
     
     
        print ("Le mot recherche est : ", mot)
        print ("Le nombre de fois que ce mot apparait est : ", result)
        #z.close()
     
    foo(texte)
    6 - Dans une expression m = re.compile(ch),
    ch est une chaine de caractères
    et m est un objet (c'est à dire une zone mémoire réservée).
    L'expression crée l'objet m de type Regular Expression Object à partir de la chaine de représentation ch.

    Cette création est un TRAVAIL pour le programme, cela représente une charge pour lui, il doit y passer un certain temps.
    Dans votre code, ce travail est répété à chaque ligne, inutilement puisque c'est pour recréer à chaque fois le même RegEx Object

    L'intérêt de la fonction compile() est justement de créer une fois pour toutes dans un programme un RegEx Object qui sera réutilisé plusieurs fois sur des chaines différentes. Les fonctions match() et search() sont, elles, utilisées plutôt quand on ne fait qu'une ou deux fois une recherche de matching avec une expression régulière précise, de façon à ne pas laisser trainer dans la mémoire vive un objet RegEx qui n'aura servi qu'une fois et qui va encombrer sans reservir.

    7 - Avec p1 = re.compile('Jean tue le (?P<text>[a-zA-Z0-9_]+)')
    le groupe est a.group(1)

    Avec p2 = re.compile('(?P<nombre>[0-9]+)')le groupe est aussi bien b.group() que b.group(1)
    Vous pouvez éviter de faire numéroter pour rien par le programme un groupe qui n'est autre que l'expression régulière entière , en écrivant plus simplement
    p2 = re.compile('?P<nombre>[0-9]+')

    Vous pouvez aussi vous passer du nommage de goupe dans la mesure où il n'y a qu'un groupe dans chacune de vos expressions régulières.
    p1 = re.compile('Jean tue le (a-zA-Z0-9_]+)')
    p2 = re.compile('[0-9]+')

    suffisent.

    8 - Dans votre code, vous explorez votre fichier en faisant extraire des lignes par l'instruction for ligne in f.

    Mais il est aussi possible de l'explorer dans sa forme native de chaine, c'est à dire de suite de caractères. Pour cela, il suffit de faire mettre le fichier dans une chaine ch par
    ch = f.read()
    puis d'utiliser les méthodes de chaine décrites ici:
    http://www.python.org/doc/2.5.2/lib/...s.html#l2h-233
    parmi lesquelles on trouve la méthode find() déjà citée mais aussi la méthode count() qui compte directement un mot dans une chaine:
    x = ch.count('monstre')

    Faisant ainsi, on n'impose par contre aucune condition sur le contexte de 'monstre'. Si vous voulez le rechercher au milieu de certains caractères l'entourant, alors il faut effectivement utiliser les regex.

  6. #6
    Membre émérite
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Par défaut
    Citation Envoyé par eyquem Voir le message
    [B][COLOR="orange"]Vous pouvez aussi vous passer du nommage de goupe
    C'est une bonne pratique de donner des noms aux groupes, ça permet de mieux s'en sortir en cas de modification d'une regex.

Discussions similaires

  1. [MySQL] compter le nombre d'un mot dans une table sql
    Par Akramweb dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 18/04/2008, 16h20
  2. Réponses: 2
    Dernier message: 28/04/2006, 13h28
  3. Compter le nombre d'octets lus dans un flux
    Par Le Furet dans le forum Entrée/Sortie
    Réponses: 25
    Dernier message: 09/03/2006, 08h19
  4. Compter le nombre d'image contenu dans un <div>
    Par denn dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 13/02/2006, 15h45
  5. [Débutant][RISC]Compter le nombre de bit à 1 dans un octet ?
    Par Pill_S dans le forum Autres architectures
    Réponses: 7
    Dernier message: 23/12/2004, 23h24

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