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 :

"Bla bla 1 , 2 bla bla" vers "Bla bla 1,2 bla bla"


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  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 "Bla bla 1 , 2 bla bla" vers "Bla bla 1,2 bla bla"
    Quelle expression régulière permet de transformer "Bla bla 1 , 2 bla bla" vers "Bla bla 1,2 bla bla" ?
    Le code suivant ne marche que si la virgule est suivie d'au moins un chiffre. Pourquoi ? Que faire ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    import re
    def remplace(m):
        return m.group(0).replace(' ', '')
     
    rx = re.compile(r'\d[0-9, ]+\d')
    txt = "Bla  bla 1,     bla bla"
    print rx.sub(remplace, txt)
    Merci.

  2. #2
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 492
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 492
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Si j'ai bien compris, on cherche le motif suivant:

    - une virgule
    - avec à sa gauche entre 0 et plusieurs espaces
    - et à sa droite entre 0 et plusieurs espaces

    Dans ce cas: motif = r"[ ]{0,}[,][ ]{0,}"
    et la chaine de remplacement: rempl = r","

    Ce qui donne:

    print re.sub(motif, rempl, "Bla bla 1 , bla bla")
    Bla bla 1,bla bla

    Tyrtamos

  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 C'est un peu plus compliqué en fait...
    En fait mon problème serait de compléter la méthode proposée dans la discussion suivante .

    Par exemple, je voudrais remplacer
    "du texte avec des espaces 12 3 45 6 encore du texte avec des espaces 1 4 , 5 ou aussi 5 6 , et voilà"
    par
    "du texte avec des espaces 123456 encore du texte avec des espaces 14,5 ou aussi 56, et voilà".

    En fait en combinant les deux méthodes, cela marche. Existe-t-il un moyen de "réunir" les deux méthodes en une seule (pour ne faire qu'un seul appel à la méthode re) ?

    PS : merci tyrtamos.

  4. #4
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 492
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 492
    Billets dans le blog
    6
    Par défaut
    Voilà une solution qui marche:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    chaine = u"du texte avec des espaces 12 3 45 6 encore du texte avec des espaces 1 4 , 5 ou aussi 5 6 ,  et voilà"
     
    motif = re.compile(r"([0-9,])[ ]+([0-9,])")
    chaine = "".join(motif.split("".join(motif.split(chaine))))
    Ce qui donne bien:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    print chaine
    du texte avec des espaces 123456 encore du texte avec des espaces 14,5 ou aussi 56,  et voilà
    En fait, le problème que j'ai rencontré est que les recherches se font sans recouvrement. C'est à dire que "1 2 3 4 5" doivent être traité 2 fois!

    Tyrtamos

  5. #5
    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
    Nickel. De nouveau merci tyrtamos.

    PS : si tu as 5min à perdre tyrtamos, peux-tu m'expliquer rapidement comment cela marche ? Une référence lisible sur le sujet me suffirait (je n'ai pas encore trouvé le temps d'apprendre à utiliser des expressions régulières mais celle proposée est claire à décoder, c'est plus l'histoire des join qui me parait très obscure...).

  6. #6
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 492
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 492
    Billets dans le blog
    6
    Par défaut
    Pour l'expression avec join, il suffit de décomposer les instructions.

    On part de:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    chaine = "du texte avec des espaces 12 3 45 6 encore du texte avec des espaces 1 4 , 5 ou aussi 5 6 ,  et voilà"
    motif = re.compile(r"([0-9,])[ ]+([0-9,])")
    Et on a en premier:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    x1 = motif.split(chaine)
    print x1
    ['du texte avec des espaces 1', '2', '3', ' 4', '5', '6', ' encore du texte avec des espaces ', '1', '4', ' ', ',', '5', ' ou aussi ', '5', '6', ' ,  et voilà']
    split() du module "re" fait la même chose que split() pour les chaines, mais utilise le motif comme critère de coupure. On voit bien que certains espaces sont éliminés, mais pas tous. Parce qu'il ne peut pas y avoir de recouvrement entre les motifs trouvés successivement: quand le motif a trouvé "2 3", il ne peut plus trouver "3 4" parce que le "3" serait commun.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    x2 = "".join(x1)
    print x2
    du texte avec des espaces 123 456 encore du texte avec des espaces 14 ,5 ou aussi 56 ,  et voilà
    join() ne fait que de reconstruire la chaine à partir de la liste x1. On voit que tous les espaces n'ont pas été traités. A la limite, si on avait "1 2 3 4 5 6", on aurait traité un espace sur 2.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    x3 = motif.split(x2)
    print x3
    ['du texte avec des espaces 12', '3', '4', '56 encore du texte avec des espaces 1', '4', ',', '5 ou aussi 5', '6', ',', '  et voilà']
    Et donc, on recommence pour traiter les espaces qui restent!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    x4 = "".join(x3)
    print x4
    du texte avec des espaces 123456 encore du texte avec des espaces 14,5 ou aussi 56,  et voilà
    Et c'est terminé!

    Ok?

    Tyrtamos

  7. #7
    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 En un seul passage
    Rassure toi, rambc, j'ai passé 2 heures hier soir à décortiquer le programme de tyrtamos pour comprendre la regex puis le procédé avec join.
    Malgré la grande admiration que j'ai pour ceux qui maitrisent à ce point les subtilités de Python, j'ai trouvé que c'est trop compliqué et aprés moult efforts je suis arrivé au programme ci-dessous.

    Je n'ai pas réussi à trouver une regex qui ne prenne pas le dernier blanc aprés toute tranche recherchée, d'où le rstrip() pour éliminer tous les blancs à droite d'une tranche trouvée dans tranches1, et d'où l'obligation de faire une liste tranches2 à partir de la première.
    Ça correspond au même problème que celui de tyrtamos sauf que ça ne concerne que le/les deniers blancs après une tranche (une tranche = [\d ,]+ ).
    Si quelqu'un trouve une regex qui évite ceci, ce sera mieux.



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import re
     
    chaine = "du texte avec des espaces 12 3 45 6 encore du texte avec des espaces 1 4 , 5 ou aussi 5 6 , et voilà"
    p = re.compile("\d[\d, ]+")
     
    tranches1= re.findall(p,chaine)
    tranches2 = [tr.rstrip() for tr in tranches1]
     
    for x in tranches2:
        chaine = chaine.replace(x,x.replace(' ',''))
     
    print chaine

  8. #8
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 492
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 492
    Billets dans le blog
    6
    Par défaut
    Et voilà plus simple que ma précédente solution:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    chaine = "du texte avec des espaces 12 3 45 6 encore du texte avec des espaces 1 4 , 5 ou aussi 5 6 ,  et voilà"
     
    motif = r"([0-9,])[ ]+([0-9,])"
    rempl = r"\1\2"
    chaine = re.sub(motif, rempl, chaine)
    chaine = re.sub(motif, rempl, chaine)
    Ou en une seule ligne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    chaine = re.sub(motif, rempl, re.sub(motif, rempl, chaine))
    2 particularités:

    => les \1 et \2 de rempl sont remplacés par les caractères effectivement trouvés de chaque côté de l'espace du motif. Cela marche un peu comme des noms de variable. Ils correspondent aux parenthèses de motif que je n'ai mises que pour ça.

    => le re.sub doit être appliqué 2 fois à cause de l'absence de recouvrement de la recherche par motif.

    Tyrtamos

  9. #9
    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 beaucoup pour les infos même si je n'ai pas trop pigé cette histoire de \1\2.

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

Discussions similaires

  1. blas/lapack en C++
    Par [Hugo] dans le forum Bibliothèques
    Réponses: 0
    Dernier message: 21/04/2009, 13h41
  2. pg_dump: missing pg_database entry for database "bla bla bla"
    Par djezair31 dans le forum PostgreSQL
    Réponses: 6
    Dernier message: 15/05/2008, 16h31
  3. BLAS: édition de liens avec libcblas.a
    Par micheldup dans le forum C++
    Réponses: 2
    Dernier message: 10/10/2007, 02h21
  4. div bla bla bla
    Par {F-I} dans le forum Mise en page CSS
    Réponses: 5
    Dernier message: 30/05/2007, 11h58
  5. [PHP-JS] $_files bla bla
    Par Cedwik dans le forum Langage
    Réponses: 12
    Dernier message: 01/09/2006, 16h26

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