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 :

Recherche d'une regex


Sujet :

Python

  1. #1
    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 Recherche d'une regex
    Bonjour,
    je voudrais passer de quelque chose comme "/Users/login/Documents/.../Music" à "/Users/login/Documents/../../../Music".

    Autrement dit, toute chaîne du type "/...../", avec ici 5 points, doit être remplacée par "/../../../../../" avec 2×5 points.

    Toute info. est la bienvenue.

  2. #2
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    On est obligé d'utiliser re, car il y a d'autres solutions

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ch="/Users/login/Documents/.../Music"
    new_ch=ch.replace("/.../", "/../../../../../")
    print new_ch
    /Users/login/Documents/../../../../../Music

  3. #3
    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
    Oui car je ne connais pas le nombre de points a priori.

  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
    Sans regex, on peut faire comme suit :
    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
    #!/usr/bin/env python3
     
    import os
     
    # Linux and Mac examples.
    def custom(path):
        i = path.find('/.')
        newPath = ''
     
        while(i >= 0):
            j = path.find('./', i)
     
            if j < i:
                break
     
            newPath += path[:i] + "/" + "../"*(j - i)
     
            path = path[j+2:]
            i = path.find('/.')
     
        if newPath:
            newPath += path
            return newPath
        else:
            return onePath
     
    for onePath in [ '/Users/login/Documents',
                     '/Users/login/Documents/./Music',
                     '/Users/login/Documents/../Documents/Misc',
                     '/Users/login/Documents/.../Documents/Misc',
                     '/Users/login/Documents/..../Documents/Misc/../Test'
                   ]:
        pathCustomized = custom(onePath)
     
        print( '',
               onePath,
               pathCustomized,
               os.path.normpath(pathCustomized),
               sep = '\n')

  5. #5
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    Avec ce code tu devrais pouvoir gérer ce que tu veux, enfin je pense

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    >>> ch="/Users/login/Documents/.../Music"
    >>> pattern='/\.+/'
    >>> search=re.findall(pattern, ch)
    >>> print search
    ['/.../']
    >>> ch_new=re.sub(pattern, "/../../../../../", ch)
    >>> print ch_new
    /Users/login/Documents/../../../../../Music

  6. #6
    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
    fred 1599,

    il faut un code qui calcule lui même la longueur de
    "/../../../../../" qu’il faut dans
    ch_new=re.sub(pattern, "/../../../../../" , ch)
    à partir de la longueur du '/...../' détecté.
    Sinon tu penses bien que ça n’a pas beaucoup d’intérêt.


    Moi j’ai ç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
    import re
    pat_slashpoints = re.compile('(/\.+)(?=/)')
     
    def slashpoints(x):
        a,b = pat_slashpoints.search(x).span()
        return ch[0:a] + (b-a-1)*'/..' + ch[b:]
     
     
    for ch in ("/Users/login/Documents/./Music",
              "/Users/login/Documents/../Music",
              "/Users/login/Documents/.../Music",
              "/Users/login/Documents/..../Music",
              "/Users/login/Documents/......./Music"):
        print slashpoints(ch)

  7. #7
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    Ah oui j'avais pas tout compris

  8. #8
    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
    Merci eyquem, c'est nickel, comme d'habitude. J'étudie le code dès que possible, et en cas de souci, je reviends ici poser des questions.

  9. #9
    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
    plus lisible:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    pat_slashpoints = re.compile('/(\.+)/')
    
    def slashpoints(x):
        a,b = pat_slashpoints.search(x).span(1)
        return ch[0:a-1] + (b-a)*'/..' + ch[b:]

  10. #10
    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
    En fait, j'ai un souci car
    "/Users/login/Documents/..../Music/.../Test"
    renvoie
    "/Users/login/Documents/../../../../Music/.../Test"
    au lieu de
    "/Users/login/Documents/../../../../Music/../../../Test".

  11. #11
    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
    J’y avais pensé mais tant que le besoin ne se faisait pas sentir, j’avais la flemme

    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
    import re
    pat_slashpoints = re.compile('/(\.+/)')
     
    def slashpoints(x):
        return ''.join( (len(y)-1)*'/..' if i%2 else y
                        for i,y in enumerate(pat_slashpoints.split(x)) )
     
    for ch in ("/Users/login/Doc.uments/./Music",
               "/Users/login/Documents/../Music",
               "/Users/log.in/Documents/.../Music",
               "/Users/login/Documents/..../Music",
               "/Users/log.in/Documents/......./Music",
               "/Users/login/Documents/..../Music/.../Test",
               "/Users/login/...../Documents/..../Music/.../Test.html"):
        print slashpoints(ch)
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def slashpoints(x):
        return ''.join( y.replace('.','/..') if i%2 else y
                        for i,y in enumerate(pat_slashpoints.split(x)) )

  12. #12
    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
    Merci pour cette modification. C'est super.

    Cela me permet de définir des chemins avec un système de parcours relatifs comme le propose Python mais sans la limitation à deux points maximums.

  13. #13
    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
    Que je suis bête. Je suis allé cherché midi à 14 heure avec la précédente manière de faire.



    Celle-ci prend 1/3 de temps en moins:

    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
    import re
     
    pit = re.compile('(/\.+)(?=/)')
     
    def slashpoints2(x):
        return pit.sub(lambda y: (len(y.group())-1)*'/..',x)
     
    te = clock()
    for ch in ("/Users/login/Doc.uments/./Music",
               "/Users/login/Documents/../Music",
               "/Users/log.in/Documents/.../Music",
               "/Users/login/Documents/..../Music",
               "/Users/log.in/Documents/......./Music",
               "/Users/login/Documents/..../Music/.../Test",
               "/Users/login/...../Documents/..../Music/.../Test.html"):
        print  slashpoints2(ch)
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def slashpoints2(x):
        def s(m): return (len(m.group())-1)*'/..'
        return pit.sub(s,x)

  14. #14
    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
    Très court... Bravo ! Il faudrait que je trouve une université d'été des regex...

  15. #15
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    Ce que je ne comprend pas c'est :

    (?=/)
    dans ton regex compilé, si tu peux m'expliquer

  16. #16
    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
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pit = re.compile('(/\.+)(?=/)')
    (?=/) est une assertion positive vers l’avant
    Elle signifie: le caractère qui suit doit être un signe /

    Une assertion négative vers l’avant s’écrit (?!.....)

    Les assertions positive et négative vers l’arrière sont
    (?<=....)
    (?<!....)




    Le but est de remplacer /...... par plusieurs /..
    Le / après les points ne doit pas êre capturé par le groupe. Mais il faut vérifier qu’il se trouve bien après la série de points: on ne doit faire de substitution de /..... que s’il s’agit d’une forme /......./
    Donc on utilise une assertion positive vers l’avant pour vérifier la présence de / après les points tout en ne l’attrapant pas dans un groupe car les assertions ne sont pas capturantes.




    ---------------------------------


    Quand on ne peut plus, on peut encore:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    pit = re.compile('/(\.+)(?=/)')
     
    def slashpoints3(x):
        return pit.sub(lambda m: len(m.group(1))*'/..',x)

  17. #17
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    Merci je me met ça dans un coin de ma tête.

    Je ne savais pas qu'on pouvait faire des assertions avec les regex.

    As-tu de la doc en ligne sur ce sujet qui en parle, je vais m'entrainer un peu?

  18. #18
    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
    Ce que je consulte le plus souvent est

    http://docs.python.org/release/2.5.4/lib/module-re.html

    particulièrement la page

    http://docs.python.org/release/2.5.4/lib/re-syntax.html

    J’aime bien la présentation dans toute la largeur de l’écran de cette version





    J’ai potassé aussi

    http://docs.python.org/howto/regex.html

    Ce tutoriel existait auparavant dans la même présentation que la doc sur re en 2.5.4 mais il semble qu’elle n’existe plus et qu’on soit obligé de consulter le lien ci-dessus





    Un très bon site:

    http://www.regular-expressions.info/python.html

    Quelque part sur ce site il y a un testeur de regex.





    Je ne pratique pas d’autres sites, je ne sais lesquels conseiller. Je sais pourtant que j’ai encore beaucoup de choses à apprendre sur les regex.

  19. #19
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    Merci beaucoup

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

Discussions similaires

  1. [RegEx] recherche d'une REGEX
    Par tdelacou dans le forum Langage
    Réponses: 3
    Dernier message: 16/01/2013, 15h48
  2. [Regex] recherche d'une regex
    Par hannibal.76 dans le forum Débuter avec Java
    Réponses: 6
    Dernier message: 14/12/2010, 19h55
  3. [Dojo] Regex : Recherche d'une valeur dans un tableau
    Par devkaty dans le forum Bibliothèques & Frameworks
    Réponses: 11
    Dernier message: 19/05/2010, 18h49
  4. Recherche d'une regex toute simple (mais pas pour moi)
    Par rambc dans le forum Général Python
    Réponses: 7
    Dernier message: 15/04/2009, 15h23
  5. [RegEx] Recherche une regex valide
    Par dondano dans le forum Langage
    Réponses: 3
    Dernier message: 13/04/2007, 19h57

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