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 :

Regex tournant infiniment


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2004
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2004
    Messages : 152
    Par défaut Regex tournant infiniment
    Bonjour à tous,

    dans une de mes applications en Python, je me connecte à IRC à l'aide d'un socket. Tout marche pour le mieux et le texte des utilisateurs sont soumis à des tests en Regex pour savoir s'il m'intéresse.

    Au bout d'un certain temps assez aléatoire l'application plante, elle utilise tout le processeur et bloque dans un regex.match(). J'ai compilé l'expression auparavant. J'ai essayé en local et il semblerait que certaine chaïne de caractère fasse tourner infiniment regex ou trop longtemps (non négligable)

    Est-ce que vous avez une idée de comment résoudre un tel problème ? Est-ce que vous avez déjà eu ce problème ?

    Merci d'avance. A bientôt.

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2004
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2004
    Messages : 152
    Par défaut
    Je rajoute quelques indications au niveau du code. Mes regex sont compilées avant d'être utilisées à l'aide de re.compile(). Elles fonctionnent très bien comme je l'ai dit sauf que elles plantent souvent.

    Lorsque j'utilise mes regex j'utilisent .match(text). J'ai déjà réglé pas mal de problème avec celles-ci car il semblerait qu'elles n'aprécient pas tous les caractères. En effet, sur certains caractères, par exemples: "!!!!!!!!", cela fait figer l'application. C'est pour cela que j'applique un filtre pour "nettoyer" les chaînes avant d'être analysée avec mes regex.

    Apparement ce n'est pas suffisant, il y a sûrement d'autres caractères sensibles. Est-ce que vous auriez des idées de solutions et autres ?
    Merci d'avance !

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2004
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2004
    Messages : 152
    Par défaut
    J'ai des nouvelles.

    C'est effectivement bien une expression régulière à l'origine d'un freeze de l'apllication. Cette analyse regex peut ne prendre aucun temps d'analyse (la plupart) mais sur certaines chaînes, cela peut aller de 1mn à >10mn.

    Ma regex est très complexe car elle se base sur des phrases, donc un humain écrit très différemment chaque fois. Bref passons, 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
    25
    26
    27
    28
    29
    #!/usr/bin/python
    from sys import argv
    import re
     
    def analyse(text):
        # --------------------------
        # Analyse du serveur
        # --------------------------
        text = " ".join(str(argv[i]) for i in range(1, (len(argv))))
        print text
        n = o.match(text)
        try:
            #print text
            if n.group(2):
                serveur = n.group(2)
            if n.group(3):
                serveur = n.group(3)
            #print "serv: %s" % (str(n.groups()))
            text = removeBlanks(text.replace(n.group(1)," ",1))
        except:
            serveur = -1
        return serveur
     
    if len(argv) <= 1:
        exit()
    else :
        o = re.compile(r'(?:[a-zA-Z0-9]*(?:^|[^a-zA-Z0-9]+))+((?:(?:(have|haben|habe|your|our|kein|no)\s?)(?:(?:server|serveur|serv|srv)))|(?:(?:(?:server|serveur|serv|srv)(?::|\s)?)(on|off|da|no)))[^a-zA-Z0-9]*')
        ana = analyse(argv[1:])
        print ana
    J'ai simplifier le code puisqu'il est dans une longue étape d'analyse. Ce n'est que dans cette portion de code que ça plante. Si j'explique ma regex, elle cherche des phrases qui contiennent "habe server" ou "have serv" ou "have srv" etc... en combinant la façon d'écrire serveur et les mots/verbes de fin ou début. C'est pour cela que c'est complexe. En résumé (habe/have/your/our/etc) + (srv/serv/server/serveur/etc) + (on/off/da). La regex accepte de combiné la deuxième () avec la première ou la dernière au minimum mais pas les deux en même temps. (Soufflez, j'ai fini avec la technique :p)
    Voici un exemple de chaîne qui va provoquer le gêle :

    #aa$aaaa since 2005 cs / cz / pes need good soutien plz !! ! communauté fr, pt, ch #aa$aaaa since 2005 cs / cz / pes need good soutien plz !! ! communauté fr, pt, ch
    ou simplement

    ., !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
    alors que un peu moins de !!! ne bloque pas
    ou encore

    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    alors que moins de ^ ne bloque pas.

    Il y a sûrement un problème dans ma regex parce que c'est avec beaucoup de ces signes que ça plante. Est-ce que vous auriez une idée ?

    Merci d'avance.

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 119
    Par défaut
    ta regex est trop compliquée car des groupes matchent des caracteres qui sont matchés par des groupes précédents. Cela fait trop de situations a verifier et ca part en temps exponentiel en nombre de caractères.
    On a le meme comportement avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    o = re.compile(r'(t*o*)+toto')
    print o.match('tttttttttttttttttttttttttttttt')
    a cause du 't' qui est d'abord dans un * puis un +, et t peut soit en faire partie soit faire partie de 'toto'. Du coup le temps croit tres vite. Il faut que tu simplifies le travail du programme en ayant des groupes qui ne s'overlappent pas par exemple. Ou bien essayer avec un parser?

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2004
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2004
    Messages : 152
    Par défaut
    Salut Fructidor et merci de ta réponse.

    En effet ma regex n'est pas du tout optimisée, ni très facile à comprendre. Le problème majeur que j'ai eut c'est comment ignorer ce qu'il y a avant ou après la regex sans inclure de [a-aA-Z1-9]* au début et à la fin.
    Pour résoudre ce problème je dois utiliser un findall au lieu du match, c'est bien ça ?

    En fait le but de cette regex est simple, c'est de détecter les mots que j'ai inclu dans la chaîne :
    Partie 1 = have|haben|habe|your|our|kein|no
    Partie 2 = server|serveur|serv|srv
    Partie 3 = on|off|da|no

    Règle de la regex: Matcher seulement si la Partie 2 est présente avec soit la Partie 1 ou la Partie 3. Tu t'y prendrais comment ?

    Merci beaucoup.

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 119
    Par défaut
    et bien je ferais une regex qui detecterait les mots (donc, en effect, un findall sur
    have|haben|habe|your|our|kein|no|server|serveur|serv|srv|on|off|da|no
    et puis je verifierais avec un algo a la main pour savoir si j'ai 1,2 et/ou 3 - histoire de rester simple.
    Sinon, c'est search qui permet d'avoir des caracteres avant et apres.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Boucle For tournant a l'infini
    Par Adrien0634 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 27/10/2010, 12h52
  2. prgram tournant côté serveur
    Par hogan dans le forum Développement
    Réponses: 8
    Dernier message: 02/02/2004, 10h54
  3. [LG]tableau infini et fonction longueur
    Par dsr57 dans le forum Langage
    Réponses: 8
    Dernier message: 13/12/2003, 13h54
  4. [regex][string] replaceAll bogué ?
    Par 7eme dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 13/11/2003, 16h36
  5. Cherche regex...
    Par laurent_h dans le forum C
    Réponses: 4
    Dernier message: 31/03/2003, 11h24

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