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 :

expression régulière négative


Sujet :

Python

  1. #1
    Nouveau Candidat au Club
    Inscrit en
    Avril 2010
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 3
    Points : 1
    Points
    1
    Par défaut expression régulière négative
    Bonjour,

    je suis relativement débutant en Python (j'utilise la version 2.6) et je suis confronté au problème suivant:

    j'ai une string qui contient à intervalles irréguliers des répétitions de 100 'N'. Je désire construire une expression régulière qui me permette de repérer TOUT CE QUI N'EST PAS ces répétions de 100 'N' (le chiffre 100 est fixe lui).
    J'arrive à repérer les 100 'N' assez facilement avec une expression du type
    re.finditer('N{100},string), mais dès que j'essaie d'inverser:
    re.finditer('[^N{100}]',...) ça ne marche plus, il se base sur tous les 'N' qu'il rencontre, même s'il n'y en a pas 100 (la string contient certains 'N' isolés que je ne veux pas repérer).

    Est-ce que l'un de vous saurait comment construire une telle expression régulière ?

    Mathieu

  2. #2
    Membre éclairé
    Avatar de airod
    Homme Profil pro
    Gérant Associé, DMP Santé et Directeur technique
    Inscrit en
    Août 2004
    Messages
    767
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Gérant Associé, DMP Santé et Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 767
    Points : 891
    Points
    891
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    import re
    a='kjtdlkjlkj44444kljdfhmkjlk'
    
    r=r'[^4{5}]+'
    
    print re.findall(r,a)

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    141
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2008
    Messages : 141
    Points : 184
    Points
    184
    Par défaut
    Salut !

    Et ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    pattern = 'N' * 100
    print machaine.split(pattern)
    Ca ne ferait pas ce que tu désires faire ?

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2010
    Messages : 53
    Points : 64
    Points
    64
    Par défaut
    Hello.

    La question étant "Je désire construire une expression régulière qui...", la proposition de nardo47 ne convient malheureusement pas.

    En ce qui concerne celle d'airod, je pense que c'est bon à condition que la chaine entre les différents blocs 'NNNNNNN' ne contiennent pas le charactère 'N'.

  5. #5
    Membre extrêmement actif
    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
    Points : 1 658
    Points
    1 658
    Par défaut
    Bonjour,



    - entre crochets, les caractères spéciaux perdent leur spécialité

    [^N{100}] représente donc un caractère qui ne doit être ni le caractère ’N’, ni le caractère ’{’, ni le caractère ’1’, ni le caractère ’0’, ni le caractère ’}’

    Par exemple,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    a='abcdef{0987098}MILIEU5fin'
    r=r'[^4{5}]+'
    print re.findall(r,a)
    donne ['abcdef', '0987098', 'MILIEU', 'fin']



    - [....] représente UNE position

    Avoir dans l’idée d’interdire une succession de caractère pour ce qui ne peut représenter qu’UNE position, ça n’a pas de sens. L’incompréhension sur ce que représente [....] est très commune.





    Comme solution au problème posé, je verrais bien l’utilisation de split() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    import re
    a='18758754XXXXX39876875363XXXXX87654-8746XXXXX'
    r=r'X{5}'
    print re.split(r,a)
    donne
    [['18758754', '39876875363', '87654-8746', '']


    Mais s’il y a un nombre nb > 5 de caractères ’X’ , il y en a nb%5 qui seront captés aussi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    import re
    a='76875363XXXXXXXXXXXXX87654-8746XXXXX'
    r=r'X{5}'
    print re.split(r,a)
    donne
    ['76875363', '', 'XXX87654-8746', '']



    Pour mieux comprendre ce qui est recherché et ce qui devrait se passer quand plus de 100 N se suivent,
    ainsi que le sens de cette indication sybilline: la string contient certains 'N' isolés que je ne veux pas repérer,
    il faudraitque l’énoncé du problème soit plus précis.

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    141
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2008
    Messages : 141
    Points : 184
    Points
    184
    Par défaut
    Citation Envoyé par miawaw Voir le message
    La question étant "Je désire construire une expression régulière qui...", la proposition de nardo47 ne convient malheureusement pas.
    Question de point de vue.

    Moi, j'ai lu surtout la suite :

    Citation Envoyé par msiol Voir le message
    [...] me permette de repérer TOUT CE QUI N'EST PAS ces répétions de 100 'N'


    L'expression régulière est dans ce cas un moyen, pas un but.

    Mais il ne s'agit que de mon interprétation.

  7. #7
    Nouveau Candidat au Club
    Inscrit en
    Avril 2010
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Ok,
    c'est bien ce qu'il me semblait, à l'intérieur, d'un set les signes {} perdent leur signification.
    Effectivement, l'expression régulière n'est pas un but en soi, ce que je veux c'est repérer les positions de début et de fin de tout ce qui n'est pas ces séries de 100 N dans ma string. Mais je dois préciser que la string est très longue (27 millions de caractères).
    Donc pour l'exemple,
    'NAAGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGTAC'
    ici je voudrais sortir :
    [[0,3],[104,107]].
    Je pensais que les expressions régulières me permettraient de m'en sortir, mais finalement, on dirait qu'il va falloir que je fasse autrement...

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    141
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2008
    Messages : 141
    Points : 184
    Points
    184
    Par défaut
    Citation Envoyé par msiol Voir le message
    ici je voudrais sortir :
    [[0,3],[104,107]].
    Je pensais que les expressions régulières me permettraient de m'en sortir, mais finalement, on dirait qu'il va falloir que je fasse autrement...
    Ah, du coup, si c'est pour avoir les positions, les regexp sont indiquées.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    >>> import re
    >>> regexp = 'spam'
    >>> chaine = 'abcdefghijklmnopqrstuvwxyzspamabcdefghijklmnopqrstuvwxyz'
    >>> match = re.search(regexp, chaine)
    >>> match.start(), match.end()
    (26, 30)
    >>> chaine[match.start():match.end()]
    'spam'
    Concernant le problème des accolades, je propose une autre syntaxe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    >>> import re
    >>> delimiter = 'N' * 100
    >>> # 'pattern1(?=pattern2)' matche sur 'pattern1' si et seulement si il est suivi par 'pattern2'
    >>> regexp = '(.*)(?=%s)' % delimiter
    >>> chaine = 'NAAGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNGTAC'
    >>> for match in re.finditer(regexp, chaine):
    	print match.start(), match.end()
     
     
    0 4
    4 4
    Bon, le résultat n'est pas totalement celui escompté (on n'a notamment pas le groupe à la fin de la chaîne), mais je trouve qu'il y a une idée à creuser ici.

    Sinon, une solution alternative, sans regexp :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    def myitersplit(chaine, delimiter):
        limit = list(delimiter)
        taille = len(limit)
        pile = []
        for x in chaine:
            pile.append(x)
            if pile[-taille:] == limit:
                yield ''.join(pile[:-taille])
                pile = []
        if pile:
            yield ''.join(pile)
    Avec un chouïa de modifications (et notamment l'appel à enumerate), on doit pouvoir récupérer les index désirés.

    Sur ce, bon courage !

  9. #9
    Membre éclairé
    Avatar de airod
    Homme Profil pro
    Gérant Associé, DMP Santé et Directeur technique
    Inscrit en
    Août 2004
    Messages
    767
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Gérant Associé, DMP Santé et Directeur technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 767
    Points : 891
    Points
    891
    Par défaut
    Citation Envoyé par msiol Voir le message
    Je pensais que les expressions régulières me permettraient de m'en sortir, mais finalement, on dirait qu'il va falloir que je fasse autrement...
    je croyais que le but premier du post etait d'obtenir une aide sur l'expression regulière pas de faire tout le boulot!

  10. #10
    Membre extrêmement actif
    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
    Points : 1 658
    Points
    1 658
    Par défaut
    Avec regex, c’est très facile...à partir du moment où on a un énoncé compréhensible.


    J’aurais aimé une précision sur le sens de ceci:
    la string contient certains 'N' isolés que je ne veux pas repérer


    «N isolés» ça veut dire quoi ? Ca se limite à un seul ou quelques uns ? Jusqu’à combien ?
    Et ne pas les repérer, ça veut dire quoi ?


    Ton exemple ne permet pas de comprendre puisqu’il est mal foutu:

    dans ’NAAGNNNNNNNNNNNNNNNNN....
    le premier N est entre 0 et 1
    'AAG' est entre 1 et 4
    et tu parles de vouloir trouver [0,3]. Sic

    De même à la fin
    ....NNNNNNNNNNNNNNNGTAC'
    La chaîne fait 108 caractères, donc ’GTAC’ est entre 104 et 108 et tu veux obtenir [104,107]. Resic.





    Bon. Partant du principe que les plages de 100 ou plus ’N’ ne t’intéressent pas mais que 10 ’N’ saupoudrés ou jointifs dans une plage de non ’N’ n’empêchent pas cette plage de non ’N d’avoir un intérêt, je propose ceci


    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
    39
    40
    41
    mport re
     
    ch1 = 'NAAGAGCTGACCAC'\
          +50*'N'\
          +'AGCTCGCTAGCTAGTCGGCTCGGTATAGGACAGATTAGACGCGATG'\
          +60*'N'\
          +'AGGC'+'NNNNNNNNNN'+'AGCTNNNGCTTTTAGCTTGCAAACATAGCCATG'\
          +70*'N'\
          +'T'+'NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN'+'AGCTTNAG'
     
    ch2 = 50*'N'\
          +'AGCTCGCTAGCTAGTCGGCTCGGTATAGGACAGATTAGACGCGATG'\
          +60*'N'\
          +'AGGC'+'NNNNNNNNNN'+'AGCTNNNGCTTTTAGCTTGCAAACATAGCCATG'\
          +70*'N'\
          +'T'+'NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN'+'AGCTTNAG'
     
    ch3 = 50*'N'\
          +'AGCTCGCTAGCTAGTCGGCTCGGTATAGGACAGATTAGACGCGATG'\
          +60*'N'\
          +'AGGC'+'NNNNNNNNNN'+'AGCTNNNGCTTTTAGCTTGCAAACATAGCCATG'\
          +70*'N'
     
    ch4 = 'AGCTCGCTAGCTAGTCGGCTCGGTATAGGACAGATTAGACGCGATG'\
          +60*'N'\
          +'AGGC'+'NNNNNNNNNN'+'AGCTNNNGCTTTTAGCTTGCAAACATAGCCATG'\
          +70*'N'
     
    pat = re.compile('N{50,}')
     
    def plages(ch):
        li=[]
        [ li.extend(m.span()) for m in pat.finditer(ch) ]
        if li[0]==0:  li.pop(0)
        else: li.insert(0,0)
        if li[-1]==len(ch):  li[-1:] = []
        else:  li.append(len(ch))     
        return [ li[k:k+2] for k in xrange(0,len(li),2) ]
     
    for ch in (ch1,ch2,ch3,ch4):
        print plages(ch)
    Dans mon exemple, j’ai pris 50 au lieu de 100 comme limite entre les succession de ’N’ qui ne sont pas voulues et les successon de ’N’ qu’on admet dans une plage de non ’N’

  11. #11
    Nouveau Candidat au Club
    Inscrit en
    Avril 2010
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    ok merci pour la réponse,

    désolé, c'était la première fois que je postais sur le site, je vais apprendre à être plus précis...
    Mais c'était effectivement ça; je suis interessé par les positions de début et de fin de tout ce qui n'est pas exactement 100 N (ou plus).

Discussions similaires

  1. [RegEx] Expression régulières : Balises <SCRIPT>
    Par Gwipi dans le forum Langage
    Réponses: 2
    Dernier message: 24/04/2006, 23h25
  2. Expression réguliére
    Par Mad_Max dans le forum Langages de programmation
    Réponses: 2
    Dernier message: 16/09/2003, 18h17
  3. [expression régulière] mon cerveau fait des noeuds..
    Par nawac dans le forum Algorithmes et structures de données
    Réponses: 7
    Dernier message: 27/05/2003, 10h06
  4. Expressions réguliéres
    Par Tooms dans le forum Langage
    Réponses: 4
    Dernier message: 06/12/2002, 18h42
  5. Réponses: 5
    Dernier message: 11/06/2002, 15h21

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