Découpage de chaînes de caractéres

a marqué ce sujet comme résolu.

Bonjour

j’ai des chaines de différents type :

type 1 :

<apply_tag name="bold">Note pour la lettre A</apply_tag>

Type 2 :

<apply_tag name="italic"> l'it<apply_tag name="bold">al</apply_tag>ique</apply_tag>

Type 3 :

<apply_tag name="underline">el la <apply_tag name="red">couleur </apply_tag>au <apply_tag name="bold">gras</apply_tag> milieu</apply_tag>

je cherche : pour le type 1 à extraire juste le texte entre > et < pour le type 2 et 3 à extraire les différents texte entre > et < avec des imbrications différentes

Merci d’avance

Remarque : les différentes chaînes sont donnés par une boucle BeautifulSoup

+0 -0

Bonjour,

tu peux utiliser le module re

In [29]: import re                                                                                                                                      

In [30]: motif = re.compile('<.+?>')                                                                                                                    

In [31]: t1 = '<apply_tag name="bold">Note pour la lettre A</apply_tag>'                                                                                

In [32]: motif.sub('', t1)                                                                                                                              
Out[32]: 'Note pour la lettre A'

In [33]: t2 = '''<apply_tag name="italic"> l'it<apply_tag name="bold">al</apply_tag>ique</apply_tag>'''                                                 

In [34]: motif.sub('', t2)                                                                                                                              
Out[34]: " l'italique"

Ce qui n’est pas evident c’est trouver le bon motif, l’exemple ci dessus supprimera aussi le texte "<k>" alors que ce n’est pas une balise, le '?' dans le motif lui évite d’être gourmand (ici sans le '?' ca supprimerait toute la chaine)

+0 -3

Bonjour et merci au final vu que j’utilise beautifulsoup dans une boucle qui me donne les différents tags :

for tag in soupTags:

avec print(tag.text) j’obtiens le texte dans un tag

mon but final est de créer un fichier .odt en utilisant Qt et QtTextDocument il faut que je décortique toutes les chaînes avec ou non des imbrications afin de recréer tous les éléments présent dans les balises avec un formatage correct; et la ça se complique !!!!

Ce qui me semble simple pour les chaines de type 1 devient complique pour le type 2 et 3 sans compter qu’au passage je perd les </br> avec BeautifullSoup

ma portion de code actuelle :

#coding: utf-8
from bs4 import BeautifulSoup
from PyQt5 import QtGui,QtCore
# Create a document object
doc = QtGui.QTextDocument()
# Create a cursor pointing to the beginning of the document
cursor = QtGui.QTextCursor(doc)

data ="""
<text><apply_tag name="titre">Thème : Equipements / Lettre A :</apply_tag><br><br>
<apply_tag name="bold">Note pour la lettre A</apply_tag>
<br><br><apply_tag name="underline">el la <apply_tag name="red">couleur </apply_tag>au <apply_tag name="bold">gras</apply_tag> milieu</apply_tag>
<br><br>le gras est dans<apply_tag name="italic"> l&apos;it<apply_tag name="bold">al</apply_tag>ique</apply_tag>
<br><br><apply_tag name="titre">Titre</apply_tag>
<br><apply_tag name="stitre1">Sous Titre 1</apply_tag>
<br><apply_tag name="stitre2">Sous Titre 2</apply_tag><br>
<apply_tag name="underline">underline</apply_tag><br>
<apply_tag name="italic">italic</apply_tag><br>
<apply_tag name="bold">gras</apply_tag><br>
<apply_tag name="strikethrough">barré</apply_tag>
<apply_tag name="left">left</apply_tag><br>
<apply_tag name="centre">center</apply_tag><br>
<apply_tag name="right">right</apply_tag><br><br>
<apply_tag name="size10">10</apply_tag><br>
<apply_tag name="size11">11</apply_tag><br>
<apply_tag name="size12">12</apply_tag><br>
<apply_tag name="size13">13</apply_tag><br>
<apply_tag name="size14">14</apply_tag><br>
<apply_tag name="size15">15</apply_tag></text>
"""

soup = BeautifulSoup(data,features="lxml")
soupTags = soup.find_all('apply_tag')

for tag in soupTags:

    if tag['name'] == 'bold':
        print(tag)
        print(str(tag).count('<apply_tag'))
        # pas d'imbrication => écriture du contenu ds fichier odf
        if str(tag).count('<apply_tag')==1:
            cursor.insertText(tag.text)
        tag.name = 'b'

        del tag['name']

    elif tag['name'] == 'italic':
        print(tag)
        tag.name = 'em'
        del tag['name']
    elif tag['name'] == 'underline':
        print(tag)
        print(str(tag).count('<apply_tag'))
        # pas d'imbrication => écriture du contenu ds fichier odf
        if str(tag).count('<apply_tag')==1:
            cursor.insertText(tag.text)
        tag.name = 'u'

        del tag['name']
    elif tag['name'] == 'strikethrough':
        print(tag)
        tag.name = 'strike'
        del tag['name']
    elif tag['name'] == 'centre':
        print(tag)
        tag.name = 'div class="wa"'
        del tag['name']
    elif tag['name'] == 'right':
        print(tag)
        tag.name = 'div style="text-align: right;"'
        del tag['name']
    elif tag['name'] == 'left':
        print(tag)
        tag.name = 'p align="left"'
        del tag['name']
    elif tag['name'] == 'titre':
        print(tag)
        tag.name = 'h1'
        del tag['name']
    elif tag['name'] == 'stitre1':
        print(tag)
        tag.name = 'h2'
        del tag['name']
    elif tag['name'] == 'stitre2':
        print(tag)
        tag.name = 'h3'
        del tag['name']
    elif tag['name'] == 'size':
        print(tag)
        tag.name = 'span style="font-size:10px"'
        del tag['name']
    elif tag['name'] == 'size10':
        print(tag)
        tag.name = 'span style="font-size:10px"'
        del tag['name']
    elif tag['name'] == 'size11':
        print(tag)
        tag.name = 'span style="font-size:11px"'
        del tag['name']
    elif tag['name'] == 'size12':
        print(tag)
        tag.name = 'span style="font-size:12px"'
        del tag['name']
    elif tag['name'] == 'size13':
        print(tag)
        tag.name = 'span style="font-size:13px"'
        del tag['name']
    elif tag['name'] == 'size14':
        print(tag)
        tag.name = 'span style="font-size:14px"'
        del tag['name']
    elif tag['name'] == 'size15':
        print(tag)
        tag.name = 'span class="wa"'
        del tag['name']
    elif tag['name'] == 'red':
        print(tag)
        tag.name = 'span style="color:#FF0000;"'
        del tag['name']      
        
# Create a writer to save the document
writer = QtGui.QTextDocumentWriter()
writer.supportedDocumentFormats()

odf_format = writer.supportedDocumentFormats()

writer.setFormat(odf_format[1])
writer.setFileName('hello_world.odt')
writer.write(doc) # Return True if successful        

au final vu que j’utilise beautifulsoup dans une boucle qui me donne les différents tags

lemarec

Salut,

Au final Beautifulsoup est simplement un wrapper autour d’une autre lib XML existante (lxml je crois). Tu peux donc traiter directement ton document comme du XML et y appliquer les opérations habituelles. Ici tu pourrais avoir une requête XPath //text() pour récupérer tous les nœuds texte du document.

Je suis un peu perdu avec les différents types, mais tu peux toujours essayer un tag.xpath('//text()') pour tous les éléments de ta liste soupTags.

Bonjour

Après pas mal de recherche, d’échecs et d’insatisfactions, voici un code que j’ai conçu moi même qui à partir d’un code sorti d’un GTK Textview (ici data, ou data1,2,3 en jouant sur les moms) un peu modifié, génère un fichier .odt avec conservation de la mise en page(gras, souligné, …) Ce n’est surement pas 100% débugé mais ça peut donner une base de travail.

Merci pour les aides

#coding: utf-8
from PyQt5 import QtGui,QtCore
from pprint import pprint
tag=""
debug=True
tags=[]
tags.append("normal")
newdata=""
data1="""<text><apply_tag name="underline">et la <apply_tag name="red">couleur </apply_tag>au <apply_tag name="bold">gras</apply_tag> milieu </apply_tag>non souligné <br>Le gras est dans<apply_tag name="italic"> l'it<apply_tag name="bold">al</apply_tag>ique</apply_tag><br></text>"""
data3="""<br><text><apply_tag name="underline">et la <apply_tag name="red">couleur </apply_tag>au <apply_tag name="bold">gras</apply_tag> milieu </apply_tag>non souligné <br>Le gras est dans<apply_tag name="italic"> l'it<apply_tag name="bold">al</apply_tag>ique</apply_tag><br><br><apply_tag name="titre">Titre</apply_tag><br><apply_tag name="stitre1">Sous Titre 1</apply_tag><br><apply_tag name="stitre2">Sous Titre 2</apply_tag><br><apply_tag name="underline">underline</apply_tag><br><apply_tag name="italic">italic</apply_tag><br><apply_tag name="bold">gras</apply_tag><br><apply_tag name="strikethrough">barré</apply_tag><br><apply_tag name="left">left</apply_tag><br><apply_tag name="centre">center</apply_tag><br><apply_tag name="right">right</apply_tag><br><br><br><apply_tag name="size10">10</apply_tag><br><apply_tag name="size11">11</apply_tag><br><apply_tag name="size12">12</apply_tag><br><apply_tag name="size13">13</apply_tag><br><apply_tag name="size14">14</apply_tag><br><apply_tag name="size15">15</apply_tag><br><br><apply_tag name="bold">Début du gras<br>celle la aussi est en gras, fin du gras</apply_tag><br><apply_tag name="blue">bleu</apply_tag><br><apply_tag name="green">vert</apply_tag><br><apply_tag name="yellow">jaune</apply_tag></text><br>"""
data2="""<br><text><apply_tag name="titre">Thème : Gtk_&_Python / Lettre L</apply_tag><apply_tag name="size12"><br><br></apply_tag><apply_tag name="titre">Listes :</apply_tag><apply_tag name="size12"><br><br></apply_tag><apply_tag name="stitre1">Recherche dans une liste</apply_tag><br><apply_tag name="size12"><br>liste.index(valeur) : renvoie l'index de la valeur trouvé dazns la liste (le plus petit), une erreur si non trouvé<br>liste[i] : renvoie la i ème valeur dans la liste<br>liste[0] : 1ère valeur<br>liste[-1] : dernière valeur<br><br></apply_tag><apply_tag name="stitre1">Tester si un élément est dans une liste : avec 'in' ou 'not in'</apply_tag><apply_tag name="size12"><br>print(valeur in liste) renvoie True ou False<br><br></apply_tag></text><br>"""
data= """<br><text><apply_tag name="titre">Thème : Equipements / Lettre P</apply_tag><br><br><apply_tag name="stitre1">PORTABLE :</apply_tag><br><br><apply_tag name="blue"><apply_tag name="size15">ACER V15 Nitro VN7-592G-72G4</apply_tag></apply_tag><br><br><apply_tag name="stitre2">SSD :</apply_tag><br><br>SSD Origine Samsung PM871 M.2 SATA MZNLM256HCCP-00000 format 2280 (un peu en dessous 850 EVO)<br><br>SSD Crucial : Bien mais chauffe 75€<br>SSD WD Black : trés bien<br>SSD Samsung 860 Evo : 100€<br>SSD Corsair moyen<br><br><apply_tag name="stitre2">Ram :</apply_tag><br><br>DDR4-2400 (ou+) SODIMM<br><br><br><br><br><br><br></text><br>"""
# Create a document object
doc = QtGui.QTextDocument()
# Create a cursor pointing to the beginning of the document
cursor = QtGui.QTextCursor(doc)
# Définition du format pour les textes du QText
current_format=QtGui.QTextCharFormat()

def setTitre(state):
    if state:
        current_format.setBackground(QtCore.Qt.gray)
        setBold(True)
        setUnderline(True)
        setSizePoint(18)
    else:
        current_format.setBackground(QtCore.Qt.white)
        setBold(False)
        setUnderline(False)
        setSizePoint(12)
        
def setSTitre1(state):
    if state:
        current_format.setBackground(QtCore.Qt.lightGray)
        setBold(False)
        setUnderline(True)
        setSizePoint(15)
    else:
        current_format.setBackground(QtCore.Qt.white)
        setBold(False)
        setUnderline(False)
        setSizePoint(12)
        
def setSTitre2(state):
    #print("<<<<<<<<< tag stitre2 (",state,") >>>>>>>")
    if state:
        setBold(True)
        setUnderline(False)
        setSizePoint(15)
    else:
        setBold(False)
        setUnderline(False)
        setSizePoint(12)        

def setSizePoint(size):
    current_format.setFontPointSize(size)

def setBold(state):
    if state:
        current_format.setFontWeight(QtGui.QFont.Bold)
    else:
        current_format.setFontWeight(QtGui.QFont.Normal)
def setItalic(state):
    if state:
        current_format.setFontItalic(True)
    else:
        current_format.setFontItalic(False) 
        
def setStrike(state):
    current_format.setFontStrikeOut(state)

def setUnderline(state):
    #print("<<<<<<<<< tag underline (",state,") >>>>>>>")
    if state:
        current_format.setUnderlineStyle(QtGui.QTextCharFormat.SingleUnderline)
    else:
        current_format.setUnderlineStyle(QtGui.QTextCharFormat.NoUnderline)

def setRed(state):
    #print("<<<<<<<<< tag red (",state,") >>>>>>>")
    if state:
        current_format.setForeground(QtCore.Qt.red)
    else:
        current_format.setForeground(QtCore.Qt.black)
        
def setBlue(state):
    #print("<<<<<<<<< tag blue (",state,") >>>>>>>")
    if state:
        current_format.setForeground(QtCore.Qt.blue)
    else:
        current_format.setForeground(QtCore.Qt.black)
        
def setGreen(state):
    #print("<<<<<<<<< tag blue (",state,") >>>>>>>")
    if state:
        current_format.setForeground(QtCore.Qt.green)
    else:
        current_format.setForeground(QtCore.Qt.black)
        
def setYellow(state):
    #print("<<<<<<<<< tag blue (",state,") >>>>>>>")
    if state:
        current_format.setForeground(QtCore.Qt.yellow)
    else:
        current_format.setForeground(QtCore.Qt.black)
        
def setNormal():    
    #print("<<<<<<<<< tag Normal >>>>>>>")
    setUnderline(False)
    setItalic(False)
    setBold(False)    
    setStrike(False)
    setSizePoint(12)

#Alignment
center_format=QtGui.QTextBlockFormat()
center_format.setAlignment(QtCore.Qt.AlignCenter)
right_format=QtGui.QTextBlockFormat()
right_format.setAlignment(QtCore.Qt.AlignRight)
left_format=QtGui.QTextBlockFormat()
left_format.setAlignment(QtCore.Qt.AlignLeft) 

def setTags():
    if len(tags)!=0:
        if tags[-1]=="titre":
            setTitre(True)
        if tags[-1]=="stitre1":
            setSTitre1(True) 
        if tags[-1]=="stitre2":
            setSTitre2(True) 
        if tags[-1]=="centre":                
            cursor.setBlockFormat(center_format)
        if tags[-1]=="right":                
            cursor.setBlockFormat(right_format)                
        if tags[-1]=="normal":
            setNormal()
        if tags[-1]=="italic":
            setItalic(True)                            
        if tags[-1]=="bold":
            setBold(True)                 
        if tags[-1]=="underline":
            setUnderline(True)
        if tags[-1]=="strikethrough":
            setStrike(True)
        if tags[-1]=="red":
            setRed(True)
        if tags[-1]=="blue":
            setBlue(True)                
        if tags[-1]=="green":
            setGreen(True)
        if tags[-1]=="yellow":
            setYellow(True)
        if tags[-1]=="size10":
            setSizePoint(10) 
        if tags[-1]=="size11":
            setSizePoint(11) 
        if tags[-1]=="size12":
            setSizePoint(12) 
        if tags[-1]=="size13":
            setSizePoint(13)
        if tags[-1]=="size14":
            setSizePoint(14) 
        if tags[-1]=="size15":
            setSizePoint(15)
    else:
        setNormal()

def setUnTags():
    if tags[-1]=="titre":
        setTitre(False)  
    if tags[-1]=="stitre1":
        setSTitre1(False) 
    if tags[-1]=="stitre2":
        setSTitre2(False)
    if tags[-1]=="centre":
        cursor.insertBlock(left_format) 
    if tags[-1]=="right":
        cursor.insertBlock(left_format)                 
    if tags[-1]=="underline":
        setUnderline(False)
    if tags[-1]=="strikethrough":
        setStrike(False)                
    if tags[-1]=="italic":
        setItalic(False)                
    if tags[-1]=="bold":
        setBold(False)                 
    if tags[-1]=="red":
        setRed(False)
    if tags[-1]=="blue":
        setBlue(False)                
    if tags[-1]=="green":
        setGreen(False)
    if tags[-1]=="yellow":
        setYellow(False)
    if tags[-1]=="size10":
        setSizePoint(12) 
    if tags[-1]=="size11":
        setSizePoint(12) 
    if tags[-1]=="size13":
        setSizePoint(12)
    if tags[-1]=="size14":
        setSizePoint(12) 
    if tags[-1]=="size15":
        setSizePoint(12)   


#########################################    
# Préparation des données à sauvegarder #
#########################################
#pprint(data)
if debug: print("Data:",data)
# Enlever les '<br>' éventuels en début et en fin
if data.find('<br>')==0:
    #print("br au début")
    data=data[4:]
if data[-1]==">" and data[-2]=="r" and data[-3]=="b" and data[-4]=="<":
    #print("br a la fin")
    data=data[:len(data)-4]
# Enlever les balises '<text>" el les '<br>' en double
data=data.replace("<text>","")
data=data.replace("</text>","")
data=data.replace("<br><br><br><br><br><br>","<br>")
data=data.replace("<br><br><br><br><br>","<br>")
data=data.replace("<br><br><br><br>","<br>")
data=data.replace("<br><br><br>","<br>")
data=data.replace("<br><br>","<br>")
# Enlever les '<br>' éventuels en début et en fin aprés suppression des balises '<text>'
if data.find('<br>')==0:
    #print("br au début")
    data=data[4:]
if data[-1]==">" and data[-2]=="r" and data[-3]=="b" and data[-4]=="<":
    #print("br a la fin")
    data=data[:len(data)-4]
# nettoyage des balises innutiles et génantes
data=data.replace('<apply_tag name="size12"><br><br></apply_tag>',"<br>")  # new
data=data.replace('<apply_tag name="size12"><br></apply_tag>',"<br>")  # new
data=data.replace('<apply_tag name="size12"></apply_tag>',"")  # new
if debug: print("Data aprés filtrage :(",data,")\n")
i=0
depart=True    
while depart:
    i+=1
    # empiler le premier tag   
    if debug: print("Initial :",data," boucle : ",i)
    t0=data.find("<")
    t1=data.find(">")
    t2=data.find("/")
    if debug: print("< en position :",t0,"- > en position :",t1,"- / en position :",t2)
    #print(element[t0:t1+1])
    if data.find('<br>')==0:
        if debug: print ("l'élément suivant est un '<br>' ")
        cursor.insertText("\n")
        data=data[4:]
    else:    
        if t0==0 and t2>t1:                     
            if debug: print ("l'élément suivant est un tag : ",data[t0:t1+1],"- Tous les tags :",tags)
            # Quel tag ?
            tagbrut=data[t0:t1+1]
            tb0=tagbrut.find('=')
            tb1=tagbrut.find('>')
            tag=tagbrut[tb0+2:tb1-1]
            tags.append(tag) # ajout du tag à la liste des tags appliqués ou à appliquer
            if debug: print ("les tags aprés ajout tag trouvé :",tags)
            # En fonction des tags retenus on applique le style
            setTags()
            data=data[t1+1:]
        if t0>0 or t0==-1:    
            if debug: print ("l'élément suivant est un texte : ",data[:t0])
            if t0>0:
                texte=data[:t0]  
                data=data[t0:]
            else:
                texte=data
                if debug: print("Texte restant : ",texte)
                depart=False
            setTags()
            if len(tags)!=0:                
                if tags[-1]=="centre": 
                    cursor.insertText(texte)
                else:
                    cursor.insertText(texte,current_format)
            else:
                cursor.insertText(texte)
        if t2<t1 and t0==0:    
            if debug: print("l'élement suivant est une fermeture de tag",data," - Longueur restante : ",len(data))
            #cursor.insertText("( DT "+tags[-1]+")")
            #enlever le dernier tag du formatage
            setUnTags()
            tag=data[t0:t1+1]  
            tags=tags[:-1]            
            data=data[t1+1:]            
            if len(data)==12:
                depart=False
                
    if i>=1000: depart=False

# Create a writer to save the document
writer = QtGui.QTextDocumentWriter()
writer.supportedDocumentFormats()
odf_format = writer.supportedDocumentFormats()
writer.setFormat(odf_format[1])
writer.setFileName('hello_world.odt')
writer.write(doc) # Return True if successful
if debug: print("FIN DE TRAITEMENT à ",i," boucles.")
True    
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte