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 :

Besoin d'aide pour remplacer avec expression régulière sur plusieurs lignes


Sujet :

Python

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2011
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 44
    Points : 30
    Points
    30
    Par défaut Besoin d'aide pour remplacer avec expression régulière sur plusieurs lignes
    Oui bonjour, je suis débutant en python et j'ai besoin d'aide pour remplacer sur plusieurs lignes avec expression régulière exemple si j'ai
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <JobProvider>
    <MaxJobPerCulture>
    <LowLife>décimal</LowLife>
    <AllAm>décimal</AllAm>
    <Suit>décimal</Suit>
    <Elite>décimal</Elite>
    </MaxJobPerCulture>
    <JobAttractivityPerCulture>
    <LowLife>décimal</LowLife>
    <AllAm>décimal</AllAm>
    <Suit>décimal</Suit>
    <Elite>décimal</Elite>
    </JobAttractivityPerCulture>
    </JobProvider>
    je voudrais remplacer le nombre décimal de chaque balise dont la partie est entre et par le même mais multiplier individuellement par variable fixe pour tout les nombres , mais voilà comme seul ces 2 balise pour cette section
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <MaxJobPerCulture>
    <LowLife>décimal</LowLife>
    <AllAm></AllAm>
    <Suit>décimal</Suit>
    <Elite>décimal</Elite>
    </MaxJobPerCulture>
    est obligatoire les autres quel que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <LowLife>décimal</LowLife>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <AllAm>décimal</AllAm>
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <Elite>décimal</Elite>
    peuvent être là (aux moins 1 des 4 minimum) aléatoirement c'est à dire présente ou non. J'ai essayer ça comme base
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # -*- coding: cp1252 -*-
    import re
    #Multiplieurs
    multiplieurCapacity = int(raw_input('entrée un nombre pour multiplier la Capacitée par '))
    def multi(MaxJobPerCulture):
        return MaxJobPerCulture.group(1) + MaxJobPerCulture.group(2) + MaxJobPerCulture.group(3) + str(int(MaxJobPerCulture.group(4)) * multiplieurCapacity) + MaxJobPerCulture.group(5) + MaxJobPerCulture.group(6) + MaxJobPerCulture.group(7)
    MaxJobPerCulture_AllAm='([\t]*<MaxJobPerCulture>)([\n\t.]*)(<AllAm>)(\d*)(</AllAm>)(\n*.*)(\n[\t]*</MaxJobPerCulture>)'
    MaxJobPerCulture_Suit='([\t]*<MaxJobPerCulture>)([\n\t.]*)(<Suit>)(\d*)(</Suit>)(\n*.*)(\n[\t]*</MaxJobPerCulture>)'
    print MaxJobPerCulture_AllAm
    print MaxJobPerCulture_Suit
    sur un exemple simple de 4 lignes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    		<MaxJobPerCulture>
    			<AllAm>décimal</AllAm>
    			<Suit>décimal</Suit>
    		</MaxJobPerCulture>
    mais ça ne marche pas, que sur la 1er balise AllAm, pas la 2ème Suit et ça peut être encore plus compliquer que ça et même dans le désordre. Ma question est simple comment faire pour que le remplacement marche sur la zone de balise d'écrit plus haut entre et ce pour des balises dans n'importe ordre et quel sois oui ou non présente?

  2. #2
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 885
    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 : 3 885
    Points : 7 233
    Points
    7 233
    Par défaut
    Je ne suis pas certain que les expressions régulières soient les plus qualifiées pour faire cela.

    Je pense plus à beautifulSoup par exemple, mais comme c'est pas ma tasse de thé ce genre de parsing, je laisse ça aux spécialistes
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  3. #3
    Membre éprouvé
    Avatar de afranck64
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2009
    Messages : 592
    Points : 1 006
    Points
    1 006
    Par défaut
    re
    je pense a une analyse avec le module xml, puis recomposition avec les nouvelles valeurs voulues (C est vrai que c est plutôt unpythonic )
    Win 10 64 bits / Linux Mint 18, - AMD A6 Quad: Py27 / Py35
    CONTENU D'UNE QUESTION
    Exemples:
    - Configuration (système d'exploitation, version de Python et des bibliothèques utilisées)
    - Code source du morceau de programme où il y a un bogue
    - Ligne de code sur laquelle le bogue apparaît
    - Erreur complète retournée pas l'interpréteur Python
    - Recherche déjà effectuée (FAQ, Tutoriels, ...)
    - Tests déjà effectués

  4. #4
    Membre éclairé

    Inscrit en
    Novembre 2008
    Messages
    418
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 418
    Points : 829
    Points
    829
    Par défaut
    Perso, je me ferais pas chier :
    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
     
    import re
    re_tag=re.compile(r'[<>]')
    we_are_in_the_MaxJobPerCulture_area = False
    of=open(out_filename, "w")
    multiplieurCapacity = int(raw_input('entrée un nombre pour multiplier la Capacitée par '))
    for l in open(le_fichier_xml):
        if "</MaxJobPerCulture>" in l:
            we_are_in_the_MaxJobPerCulture_area = False
        if we_are_in_the_MaxJobPerCulture_area:
            splitted_line = re_tag.split(l)
            new_val = float(splitted_line[2]) * multiplieurCapacity
            new_line = "<%s>%.2f<%s>\n" % (splitted_line[1], new_val, splitted_line[3])
            of.write(new_line)
        else
            of.write(l)
        if "<MaxJobPerCulture>" in l:
            we_are_in_the_MaxJobPerCulture_area = True
    ou un truc du genre.
    Je n'ai pas le temps de tester aussi, c'est peut-être bugué mais le principe est là.
    Il est clair qu'en passant par un parser, genre BeautifulSoup, ce serait plus beau. Mais pour un truc comme ça, c'est peut-être pas nécessaire de se compliquer la vie :-)

  5. #5
    Membre éprouvé
    Avatar de afranck64
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2009
    Messages : 592
    Points : 1 006
    Points
    1 006
    Par défaut
    Après du brute force, je viens trouver une expression qui "match".
    Mais il faut revoire vos "groups"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import re
     
    pat = r'([\t]*<MaxJobPerCulture>).*(\n+\t*)*(<AllAm>)(\d*\D*)(</AllAm>)(\n*).*(\n[\t]*</MaxJobPerCulture>)'
    txt = """             <MaxJobPerCulture>
                            <AllAm>décimal</AllAm>
                            <Suit>décimal</Suit>
                    </MaxJobPerCulture>"""
     
    res = re.match(pat, txt)
    print res.groups()
    Win 10 64 bits / Linux Mint 18, - AMD A6 Quad: Py27 / Py35
    CONTENU D'UNE QUESTION
    Exemples:
    - Configuration (système d'exploitation, version de Python et des bibliothèques utilisées)
    - Code source du morceau de programme où il y a un bogue
    - Ligne de code sur laquelle le bogue apparaît
    - Erreur complète retournée pas l'interpréteur Python
    - Recherche déjà effectuée (FAQ, Tutoriels, ...)
    - Tests déjà effectués

  6. #6
    Membre éprouvé
    Avatar de afranck64
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2009
    Messages : 592
    Points : 1 006
    Points
    1 006
    Par défaut
    En plus nettoyé
    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 = r'[\t\n]*(<MaxJobPerCulture>).*(?:\n+\t*)*(<AllAm>)(?P<node0>\d*\D*)(</AllAm>)(?:\n*).*\n[\t]*(</MaxJobPerCulture>)[\t\n]*'
    txt = """             <MaxJobPerCulture>
                            <AllAm>décimal</AllAm>
                            <Suit>décimal</Suit>
                    </MaxJobPerCulture>
     
            """
     
    res = re.match(pat, txt)
    print res
    print res.groups()
    print res.groupdict())
    Win 10 64 bits / Linux Mint 18, - AMD A6 Quad: Py27 / Py35
    CONTENU D'UNE QUESTION
    Exemples:
    - Configuration (système d'exploitation, version de Python et des bibliothèques utilisées)
    - Code source du morceau de programme où il y a un bogue
    - Ligne de code sur laquelle le bogue apparaît
    - Erreur complète retournée pas l'interpréteur Python
    - Recherche déjà effectuée (FAQ, Tutoriels, ...)
    - Tests déjà effectués

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2011
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 44
    Points : 30
    Points
    30
    Par défaut
    Merci à tous pour vos réponse, et le code de fatbob semble le plus proche de ce que je veut à quelque chose prêt c'est que les tabulations présente à l'origine du fichier sur les balises à remplacer sont manquante il y a t'il un moyen de les remettre les tabulation automatique et ce quel que sois leur nombre? Le code que j'ai légèrement remanier
    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
    # -*- coding: cp1252 -*-
    import re
    re_tag=re.compile(r'[<>]')
    we_are_in_the_MaxJobPerCulture_area = False
    of=open('destination', "w")
    multiplieurCapacity = int(raw_input('entrée un nombre pour multiplier la Capacitée par '))
    for l in open("source"):
        if "</MaxJobPerCulture>" in l:
            we_are_in_the_MaxJobPerCulture_area = False
        if we_are_in_the_MaxJobPerCulture_area:
            splitted_line = re_tag.split(l)
            new_val = int(splitted_line[2]) * multiplieurCapacity
            new_line = "<%s>%.i<%s>\n" % (splitted_line[1], new_val, splitted_line[3])
            of.write(new_line)
        else:
            of.write(l)
        if "<MaxJobPerCulture>" in l:
            we_are_in_the_MaxJobPerCulture_area = True
    raw_input('Appuie sur <Entrée> ...')
    à la place de float j'ai mis int parce que c'est obligatoirement un entier pas virgule flottant et aussi %.i à la place de %.2f pour éviter le point et avoir un nombre illimités.

    Et encore merci pour votre aide précieuse!

    MediaVistaIntel

  8. #8
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 885
    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 : 3 885
    Points : 7 233
    Points
    7 233
    Par défaut
    Il est clair qu'en passant par un parser, genre BeautifulSoup, ce serait plus beau. Mais pour un truc comme ça, c'est peut-être pas nécessaire de se compliquer la vie :-)
    Euh... C'est pas plutôt le contraire?
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  9. #9
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 885
    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 : 3 885
    Points : 7 233
    Points
    7 233
    Par défaut
    Juste avec xml.dom.minidom

    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
    46
    >>> from xml.dom import minidom
     
    >>> xml = """<JobProvider>
    ... <MaxJobPerCulture>
    ... <LowLife>décimal</LowLife>
    ... <AllAm>décimal</AllAm>
    ... <Suit>décimal</Suit>
    ... <Elite>décimal</Elite>
    ... </MaxJobPerCulture>
    ... <JobAttractivityPerCulture>
    ... <LowLife>décimal</LowLife>
    ... <AllAm>décimal</AllAm>
    ... <Suit>décimal</Suit>
    ... <Elite>décimal</Elite>
    ... </JobAttractivityPerCulture>
    ... </JobProvider>"""
     
    >>> xmldoc = minidom.parseString(xml)
     
    >>> job = xmldoc.firstChild
    >>> print job.toxml()
    <JobProvider>
    <MaxJobPerCulture>
    <LowLife>décimal</LowLife>
    <AllAm>décimal</AllAm>
    <Suit>décimal</Suit>
    <Elite>décimal</Elite>
    </MaxJobPerCulture>
    <JobAttractivityPerCulture>
    <LowLife>décimal</LowLife>
    <AllAm>décimal</AllAm>
    <Suit>décimal</Suit>
    <Elite>décimal</Elite>
    </JobAttractivityPerCulture>
    </JobProvider>
     
    >>> job.childNodes
    [<DOM Text node "u'\n'">, <DOM Element: MaxJobPerCulture at 0x7f1a31cc67a0>, <DOM Text node "u'\n'">, <DOM Element: JobAttractivityPerCulture at 0x7f1a31cc6d40>, <DOM Text node "u'\n'">]
     
    >>> print job.childNodes[1].toxml()
    <MaxJobPerCulture>
    <LowLife>décimal</LowLife>
    <AllAm>décimal</AllAm>
    <Suit>décimal</Suit>
    <Elite>décimal</Elite>
    </MaxJobPerCulture>
    J'ai super détaillé, tu peux suivre le tuto assez explicite

    Voici un code que je me suis amusé à faire pour récupérer les valeurs en connaissant le nom du tag

    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
    from xml.dom import minidom
     
    class Tag():
        def __init__(self, name):
            self.name = name
        def getvalue(self, objet_xml):
            try:
                value = objet_xml.getElementsByTagName(self.name)
                value = value[1].childNodes
                value = value[0].wholeText
            except IndexError:
                value = ''
            return value
     
    xml ="""<JobProvider>
    <MaxJobPerCulture>
    <LowLife>décimal</LowLife>
    <AllAm>décimal</AllAm>
    <Suit>décimal</Suit>
    <Elite>décimal</Elite>
    </MaxJobPerCulture>
    <JobAttractivityPerCulture>
    <LowLife>décimal</LowLife>
    <AllAm>décimal</AllAm>
    <Suit>décimal</Suit>
    <Elite>décimal</Elite>
    </JobAttractivityPerCulture>
    </JobProvider>"""
     
    xmldoc = minidom.parseString(xml) # utiliser la fonction parse() pour un fichier xml
     
    low = Tag('LowLife')
     
    print low.getvalue(xmldoc) # retourne comme prévu décimal
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  10. #10
    Membre éclairé

    Inscrit en
    Novembre 2008
    Messages
    418
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 418
    Points : 829
    Points
    829
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Euh... C'est pas plutôt le contraire?
    Ca dépend ce que l'on appelle compliqué.
    Si l'on inclut dans le temps de développement le temps nécessaire à la compréhension du module, je ne suis pas certain que l'utilisation d'un parser xml soit plus simple (mes premiers pas avec Beautiful Soup ont été très lents).

    Après, il est clair que pour quelqu'un qui maîtrise le sujet, c'est plus propre et plus adapté à de futures évolutions.
    Malgré tout, avec de simples expressions régulières, le code nécessaire pour effectuer la tâche demandée n'est pas très important.
    Par contre, dès lors où il faut naviguer réellement dans l'arbre xml, la méthode que j'ai exposé ne tient plus la route.

  11. #11
    Membre éclairé

    Inscrit en
    Novembre 2008
    Messages
    418
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 418
    Points : 829
    Points
    829
    Par défaut
    Citation Envoyé par MediaVistaIntel Voir le message
    y a-t-il un moyen de remettre les tabulation automatiquement ?
    Bien sûr
    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
    # -*- coding: cp1252 -*-
    import re
    re_tag=re.compile(r'[<>]')
    we_are_in_the_MaxJobPerCulture_area = False
    of=open('destination', "w")
    multiplieurCapacity = int(raw_input('entrée un nombre pour multiplier la Capacitée par '))
    for l in open("source"):
        if "</MaxJobPerCulture>" in l:
            we_are_in_the_MaxJobPerCulture_area = False
        if we_are_in_the_MaxJobPerCulture_area:
            splitted_line = re_tag.split(l)
            new_val = int(splitted_line[2]) * multiplieurCapacity
            new_line = "%s<%s>%.i<%s>\n" % (splitted_line[0], splitted_line[1], new_val, splitted_line[3])
            of.write(new_line)
        else:
            of.write(l)
        if "<MaxJobPerCulture>" in l:
            we_are_in_the_MaxJobPerCulture_area = True
    raw_input('Appuie sur <Entrée> ...')

  12. #12
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2011
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 44
    Points : 30
    Points
    30
    Par défaut
    Un très grand merci à toi fatbob tu à résolu mon problème en entier et avec les tabulations respecter je mais donc résolu pour ce topic.

    Encore Bravo et encore Merci fatbob!!!

    MediaVistaIntel

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 29/08/2012, 15h44
  2. besoin d'aide pour developpez avec zope
    Par falifalibe dans le forum Zope
    Réponses: 1
    Dernier message: 08/03/2009, 10h36
  3. expression régulière sur plusieurs lignes
    Par [Hugo] dans le forum Langage
    Réponses: 6
    Dernier message: 01/07/2008, 12h48
  4. [JQuery] Besoin d'aide pour formulaire avec AJAX
    Par noz62 dans le forum jQuery
    Réponses: 5
    Dernier message: 19/06/2008, 22h38
  5. Réponses: 0
    Dernier message: 02/04/2008, 20h29

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