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 :

Amélioration d'un "split" un peu évolué


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 Amélioration d'un "split" un peu évolué
    Bonjour,
    désolé pour ce titre.

    Voici mon problème : je voudrais éclater la chaîne
    "Un premier test : ¨mefs et ¨mef.Encore des ¨mefs..."
    sous la forme
    ["Un premier test : ", "¨mefs", " et ", "¨mef", ".Encore des ", "¨mefs", "..."].

    J'ai fait 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
    36
    37
    38
    #! /usr/bin/env python3
     
    import re
     
    PATTERN = re.compile("¨\w+")
     
    def splitForReplace(text):
        textSplitted = []
     
        for onePieceWithNoAbrev in PATTERN.split(text):
            start = text.find(onePieceWithNoAbrev)
            end = start + len(onePieceWithNoAbrev)
     
            before = text[:start] # One possible abreviation.
            if before:
                textSplitted.append(before)
            textSplitted.append(text[start:end])
     
            text = text[end:]
     
        if text:
            textSplitted.append(text)
     
        return textSplitted
     
     
    if __name__ == '__main__':
        tests = [
                  'Circulez, y a rien à voir !',
                  'Un premier test : ¨mefs et ¨mef.Encore des ¨mefs...',
                  'Un autre test :¨mef,¨Mef, ¨MEF, ¨MeF...',
                ]
     
        for oneTest in tests:
            print( '---',
                   oneTest.strip(),
                   splitForReplace(oneTest),
                   sep = '\n' )
    Ce code renvoie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ---
    Circulez, y a rien à voir !
    ['Circulez, y a rien à voir !']
    ---
    Un premier test : ¨mefs et ¨mef.Encore des ¨mefs...
    ['Un premier test : ', '¨mefs', ' et ', '¨mef', '.Encore des ', '¨mefs', '...']
    ---
    Un autre test :¨mef,¨Mef, ¨MEF, ¨MeF...
    ['Un autre test :', '¨mef', ',', '¨Mef', ', ', '¨MEF', ', ', '¨MeF', '...']
    Tout ceci me permet de repérer les séquences ¨word pour faire des remplacements au cas par cas. Peut-être que les regex permettent directement cela...

    Avez-vous d'autres méthodes à proposer ?

  2. #2
    Membre Expert
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 068
    Par défaut
    on peut avoir une chaine genre:
    ou il y a forcement un caractere non alphabétique entre chaque portion ?

    et est-ce qu' "¨" est toujours précédé d'un espace ?

  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
    Bonjour josmiley.

    Citation Envoyé par josmiley Voir le message
    on peut avoir une chaine genre:
    Oui.

    Citation Envoyé par josmiley Voir le message
    il y a forcement un caractere non alphabétique entre chaque portion ?
    Non.

    Citation Envoyé par josmiley Voir le message
    et est-ce qu' "¨" est toujours précédé d'un espace ?
    Non.

    C'est pour cela que j'ai fait la fonction ci-dessus qui au passage ne marche pas avec "xxx¨mef¨Mef..." qui doit devenir ["xxx", "¨mef", "¨Mef", "..."]. Je vais rectifier ceci.

  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
    Voici un patch résolvant le problème ci-dessus :
    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
    42
    43
    44
    45
    #! /usr/bin/env python3
     
    import re
     
    PATTERN = re.compile("¨\w*")
     
    def splitForReplace(text):
        textSplitted = []
     
        for onePieceWithNoAbrev in PATTERN.split(text):
            start = text.find(onePieceWithNoAbrev)
            end = start + len(onePieceWithNoAbrev)
     
            possibleAbrev = text[:start]
            onlyText = text[start:end]
     
            if possibleAbrev:
                for x in possibleAbrev.split('¨'):
                    if x:
                        textSplitted.append('¨' + x)
     
            if onlyText:
                textSplitted.append(onlyText)
     
            text = text[end:]
     
        if text:
            textSplitted.append(text)
     
        return textSplitted
     
     
    if __name__ == '__main__':
        tests = [
                  'Circulez, y a rien à voir !',
                  'Un premier test : ¨mefs et ¨mef.Encore des ¨mefs...',
                  'Un autre test :¨mef,¨Mef, ¨MEF, ¨MeF...',
                  'xxx¨mef¨Mef ...',
                ]
     
        for oneTest in tests:
            print( '---',
                   oneTest.strip(),
                   splitForReplace(oneTest),
                   sep = '\n' )
    Une fois lancé, on obtient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ---
    Circulez, y a rien à voir !
    ['Circulez, y a rien à voir !']
    ---
    Un premier test : ¨mefs et ¨mef.Encore des ¨mefs...
    ['Un premier test : ', '¨mefs', ' et ', '¨mef', '.Encore des ', '¨mefs', '...']
    ---
    Un autre test :¨mef,¨Mef, ¨MEF, ¨MeF...
    ['Un autre test :', '¨mef', ',', '¨Mef', ', ', '¨MEF', ', ', '¨MeF', '...']
    ---
    xxx¨mef¨Mef ...
    ['xxx', '¨mef', '¨Mef', ' ...']

  5. #5
    Membre Expert
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Par défaut
    Je l'ai testé en Python 2.6, mais cela devrait fonctionner en Python 3:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    import re
    from itertools import chain
     
    PATTERN = re.compile('([^¨]*)(¨\w+)?')
    def split_for_replace(text):
        return filter(None, chain.from_iterable(PATTERN.findall(text)))

  6. #6
    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.

    Cela fonction sous Python3, et c'est bien plus court (même si on utilise la grande artillerie).

  7. #7
    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 rambc Voir le message
    Tout ceci me permet de repérer les séquences ¨word pour faire des remplacements au cas par cas. Peut-être que les regex permettent directement cela...
    Est-ce que ceci ne suffirait pas ?
    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
    >>> s = "Un premier test : ¨mefs et ¨mef.Encore des ¨mefs..."
    >>> s
    'Un premier test : ¨mefs et ¨mef.Encore des ¨mefs...'
    >>> pattern = r"¨(\w+)"
    >>> def remplacement(match):
    ...     print("Je remplace " + match.group(1))
    ...     return "remplacement"
    ... 
    >>> re.sub(pattern, remplacement, s)
    Je remplace mefs
    Je remplace mef
    Je remplace mefs
    'Un premier test : remplacement et remplacement.Encore des remplacement...'

  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 mais en fait suivant la chaîne "¨word" obtenue, le remplacement sera différent. C'est ce que j'entendais par au cas par cas.
    Par exemple, j'associe "¨py" à "Python le fabuleux", et "¨VBA" à "Very Bad Application".
    Dans ce cas, je veux transformer
    "Qui ne connait pas ¨py ? J'ai commencé avec ¨VBA et je ne voudrais plus avoir à l'utiliser. Par contre, ceci n'est pas une ¨abréviation."
    en
    "Qui ne connait pas Python le fabuleux ? J'ai commencé avec Very Bad Application et je ne voudrais plus avoir à l'utiliser. Par contre, ceci n'est pas une ¨abréviation.".

  9. #9
    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
    Eh bien, un peu d'adaptation suffira... Je présume que tu voudras stocker les remplacements dans un dictionnaire.

    Voici une possibilité :
    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
    >>> class Remplaceur(dict):
    ...     pattern = re.compile(r"¨(\w+)")
    ...     
    ...     def traduire(self, string):
    ...         return self.pattern.sub(self.remplacer, string)
    ...     
    ...     def remplacer(self, match):
    ...         return self.get(match.group(1), match.group(0))
    ... 
    >>> string = "Qui ne connait pas ¨py ? J'ai commencé avec ¨VBA et je ne voudrais plus avoir à l'utiliser. Par contre, ceci n'est pas une ¨abréviation."
    >>> r = Remplaceur()
    >>> r["py"] = "Python le fabuleux et l'unique"
    >>> r["VBA"] = "Very Bad Application"
    >>> r.traduire(string)
    "Qui ne connait pas Python le fabuleux et l'unique ? J'ai commencé avec Very Bad Application et je ne voudrais plus avoir à l'utiliser. Par contre, ceci n'est pas une ¨abréviation."
    En passant, la méthode str.format offre ce genre d'outils.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> d = {"monde":"Python"}
    >>> "Bonjour {monde}".format(**d)
    'Bonjour Python'

  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
    Bonjour.
    Citation Envoyé par Antoine_935 Voir le message
    Eh bien, un peu d'adaptation suffira... Je présume que tu voudras stocker les remplacements dans un dictionnaire.
    Merci. J'ai adapté mon code avec ta méthode. Résultat : un code court. Génial !

    Citation Envoyé par Antoine_935 Voir le message
    En passant, la méthode str.format offre ce genre d'outils.
    On est d'accord mais dans le cadre de mon projet les abréviations s'écrivent ¨nom_abrev.

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

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