[Help] Découper des textes en groupes de mots

Fermé
zograme Messages postés 23 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 1 mars 2011 - 1 mars 2011 à 14:08
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 - 1 mars 2011 à 21:28
Bonjour,

je cherche une solution pour découper automatiquement les phrases d'un texte. L'idée, c'est que mes phrases ne doivent pas dépasser une certaine longueur. Vous avez une idée?

A voir également:

18 réponses

heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
Modifié par heyquem le 1/03/2011 à 19:40
Oui Python c'est bon.
"Life is short. You need Python"

Encore faut il que le codeur ait les idées bien en place.

J'ai corrigé le code pour tenir compte du cas où il n'y a pas de blanc avant la longueur_max
Dans ce cas, le code jusqu'à présent produisait un - 1 comme résultat de
x = line[0:longueur_max].rfind(' ')
Par conséquent l'instruction line = line[x+1:] équivalait à
line = line[0:] ce qui veut dire que line reprenait la même valeur, donc boucle infinie (le while)
Pour ce cas, le programme coupe maintenant à longueur_max sans état d'âme, sans se préoccuper s'il coupe un mot ou non.


Le replace('.txt','bis.txt') ajoute une extension 'bis' au nom du fichier créé, pour ne pas écraser le précédent.

Tu pourras adapter ce code avec l'autre qui réécrit dans le mêm fichier que lu


from os import walk,sep 

def file_squeezer(path, longueur_max = 30): 

    print 'path==',path 
    with open(path) as f: 
        li = f.readlines() 
        print li 
        print 

    for i in xrange(len(li)-1,-1,-1): 

        line = li[i].rstrip() 
        decoup = [] 
        while len(line)>longueur_max: 
            x = line[0:longueur_max].rfind(' ') 
            decoup.append(line[0:x if x>0 else longueur_max]) 
            line = line[x+1 if x>0 else longueur_max:] 
        decoup.append(line) 
        li[i:i+1] = decoup 

    with open(path.replace('.txt','bis.txt'),'w') as f: 
        f.write('\n'.join(li)) 
         
    
for dirpath,dirnames,filenames in walk('C:\\contenant'): 
    print 
    print "dirpath==",dirpath 
    print "\ndirnames==",dirnames 
    print '\nfilenames==',filenames,'\n' 
    for filename in filenames: 
        file_squeezer(dirpath+sep+filename) 
        print '------------------------------------------'



J'oubliais:
la fonction os.walk() explore récursivement tous les dossiers contenus dans le dossier qu'on lui passe comme argument

On peut complexifier pour faire des chose plus salées (habituellement quand on complexifie, ce n'est pas pour faire des choses plus simple...:)
2
zograme Messages postés 23 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 1 mars 2011
1 mars 2011 à 20:27
Alors là je suis complètement largué... Je le lance, mais rien ne se passe...
Du coup j'ai essayé de renseigner manuellement le path à la ligne 5, ou à for dirpath,dirnames,filenames in walk('C:\\contenant'):

Yo no comprendo :P
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
1 mars 2011 à 20:46
As tu remplacé 'C:\\contenant' par le chemin de ton dossier à toi ?

Sinon, si tu continues à avoir des problèmes, place des instructions

print 'je passe ici 1'
print "j'ai fait ceci"
print "j'ai fait cela UUUUUUUUUUuuu'

etc

à divers endroits dans le code pour voir où ça plante
0
zograme Messages postés 23 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 1 mars 2011
1 mars 2011 à 20:47
J'ai changé le c:\\contenant oui. Pourquoi \\ d'ailleurs?
0
zograme Messages postés 23 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 1 mars 2011
1 mars 2011 à 20:52
A priori c'est à partir de

def file_squeezer(path, longueur_max = 26):

Code =

from os import walk,sep

print 'je passe ici 1'

def file_squeezer(path, longueur_max = 26):

print 'arf'

print 'path==',path
with open(path) as f:
li = f.readlines()
print li
print

for i in xrange(len(li)-1,-1,-1):

line = li[i].rstrip()
decoup = []
while len(line)>longueur_max:
x = line[0:longueur_max].rfind(' ')
decoup.append(line[0:x if x>0 else longueur_max])
line = line[x+1 if x>0 else longueur_max:]
decoup.append(line)
li[i:i+1] = decoup

with open(path.replace('.txt','bis.txt'),'w') as f:
f.write('\n'.join(li))
print "j'ai fait ceci"

for dirpath,dirnames,filenames in walk('C:\\contenant'):
print
print "dirpath==",dirpath
print "\ndirnames==",dirnames
print '\nfilenames==',filenames,'\n'
for filename in filenames:
file_squeezer(dirpath+sep+filename)
print '------------------------------------------'



'je passe ici1' s'affiche, pas 'arf', mais 'j'ai fait ceci' s'affiche...
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
1 mars 2011 à 20:59
Ca doit être le nom du dossier de départ.
Je viens d'essayer avec un mauvais nom => rien

Voici le code complété pour vérif du nom d dossier


from os import walk,sep
from os.path import isdir
from sys import exit

# données à fixer 
dossier_de_depart = 'C:\\contenant'
longueur_max = 30

def file_squeezer(path, lm = longueur_max): 

    print 'path==',path 
    with open(path) as f: 
        li = f.readlines() 
        print li 
        print 

    for i in xrange(len(li)-1,-1,-1): 

        line = li[i].rstrip() 
        decoup = [] 
        while len(line)>lm: 
            x = line[0:lm].rfind(' ') 
            decoup.append(line[0:x if x>0 else lm]) 
            line = line[x+1 if x>0 else lm:] 
        decoup.append(line) 
        li[i:i+1] = decoup 

    with open(path.replace('.txt','bis.txt'),'w') as f: 
        f.write('\n'.join(li)) 
         


if not isdir(dossier_de_depart):
    message = 'Mauvais nom de dossier:  ' + dossier_de_depart
    exit(message)
    
    
for dirpath,dirnames,filenames in walk(dossier_de_depart): 
    print 
    print "dirpath==",dirpath 
    print "\ndirnames==",dirnames 
    print '\nfilenames==',filenames,'\n' 
    for filename in filenames: 
        file_squeezer(dirpath+sep+filename) 
        print '------------------------------------------'
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
Modifié par heyquem le 1/03/2011 à 17:29
Je t'envoie ce brouillon pour que tu puises commencer à faire tourner et voir comment ça marche

with open('C:\\Glee.txt') as f: 
    li = f.readlines() 
    for x in li: 
        print len(x),repr(x) 
print '=================================================\n' 
longueur_max = 30 

for i in xrange(len(li)-1,-1,-1): 
    line = li[i] 
    print len(line),repr(line) 
    line = li[i].rstrip() 
    decoup = [] 
    while len(line)>longueur_max: 
        x = line[0:longueur_max].rfind(' ') 
        print 'x==',x,line[x:x+8] 
        decoup.append(line[0:x]) 
        line = line[x+1:] 
        print len(line),repr(line) 
    print '----------------' 
    li[i:i+1] = decoup 

print 
print '------------------------------------------------------' 
print li 


print '\n'.join(li)
1
zograme Messages postés 23 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 1 mars 2011
1 mars 2011 à 17:30
OK, super. Je teste ça de suite.
0
zograme Messages postés 23 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 1 mars 2011
1 mars 2011 à 17:38
Ça a l'air de marcher nickel!! Quelle instruction faut-il ajouter pour qu'il me le sorte dans un fichier, ou même qu'il m'écrase le fichier d'origine?
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
1 mars 2011 à 17:49
non ce code n'est pas nickel
j'avais oublié l'instruction decoup.append(line) après la boucle while

for i in xrange(len(li)-1,-1,-1):
c'est pour traiter les lignes à partir de la dernière.
Sinon, si on fait des insertions dans une liste en Python en commençant par le début on n'itère plus sur les éléments initiaux de la liste, mais au fur et à mesure qu'on en rajoute sur les nouveaux aussi
C'est de la cuisine.

Le code suivant est bon je pense.
Mais attends, je te récris avec ce que tu as demandé
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
Modifié par heyquem le 1/03/2011 à 17:41
Voilà, je crois que c'est fait


with open('C:\\Glee.txt') as f: 
    li = f.readlines() 
    for x in li: 
        print len(x),repr(x) 
print '=================================================\n' 
longueur_max = 30 

for i in xrange(len(li)-1,-1,-1): 
    line = li[i] 
    print 'ligne initiale : ',len(line),repr(line) 
    line = li[i].rstrip() 
    decoup = [] 
    while len(line)>longueur_max: 
        x = line[0:longueur_max].rfind(' ') 
        print 'x==',x,repr(line[x:x+8]) 
        decoup.append(line[0:x]) 
        print 'chaine mise dans decoup : ',len(line[0:x]),repr(line[0:x]) 
        line = line[x+1:] 
        print 'chaine restant à traiter : ',len(line),repr(line) 
    print 'morceau restnt à inclure dans decoup : ',line 
    decoup.append(line) 
    li[i:i+1] = decoup 
    print 'liste decoup dont les éléments prennent la place de la ligne initiale :\n' 
    print decoup 
    print '----------------' 


print 
print '------------------------------------------------------' 
print li 


print '\n'.join(li)






Tu prends ce code, tu enlèves tous les print, sauf le dernier, et tu as le texte avec des lignes raccourcies à la longueur_max.
1
zograme Messages postés 23 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 1 mars 2011
1 mars 2011 à 17:53
Super, je teste ça. Dsl pour ma lenteur, connexion internet à la Réunion. C'est pas le top ^^
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
1 mars 2011 à 18:02
ah bon, La Réunion

tu as compris que tu pourras fixher longueur_max à ta convenance,
que les lignes sont découpées en fonction du dernier blanc avant la longueur max (sinon les mots seraient coupés au milieu), et que le +1 dans line = line[x+1:] est pour découper après le blanc qui a été détecté

+ d'une demi-heure à faire; mais j'aimerais bien voir faire ça en C++ ou C, ou même en Java
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
1 mars 2011 à 17:55
Le code suivant crée un autre fichier que lepremier qui est conservé, ceci par sécurité:

with open('C:\\Glee.txt') as f:
    li = f.readlines()

longueur_max = 30

for i in xrange(len(li)-1,-1,-1):
    line = li[i].rstrip()
    decoup = []
    while len(line)>longueur_max:
        x = line[0:longueur_max].rfind(' ')
        decoup.append(line[0:x])
        line = line[x+1:]
    decoup.append(line)
    li[i:i+1] = decoup


with open('C:\\Glee2.txt','w') as f:
    f.write('\n'.join(li))



Si le programme est jugé fiable, on peut faire réécrire le texte traité dans le même fichier:


with open('C:\\Glee.txt','r=') as f:
    li = f.readlines()

    longueur_max = 30

    for i in xrange(len(li)-1,-1,-1):
        line = li[i].rstrip()
        decoup = []
        while len(line)>longueur_max:
            x = line[0:longueur_max].rfind(' ')
            decoup.append(line[0:x])
            line = line[x+1:]
        decoup.append(line)
        li[i:i+1] = decoup

    f.seek(0,0)
    f.write('\n'.join(li))
        
1
zograme Messages postés 23 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 1 mars 2011
1 mars 2011 à 18:10
J'ai essayé de mettre un *.txt pour traiter plusieurs fichiers d'un coup, mais cela n'a pas l'air de lui plaire. Que me conseilles tu?
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
1 mars 2011 à 18:29
ah ben non , non non , pas comme ça

attends, je reviens , là

je vais te faire ça
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
1 mars 2011 à 18:43
je viens de corriger une erreur dans le second code

c'est with open('C:\\Glee.txt','r+') as f:
et non pas
with open('C:\\Glee.txt','r=') as f:
0
zograme Messages postés 23 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 1 mars 2011
1 mars 2011 à 19:12
Je recois un

Traceback (most recent call last):
File "J:\Découp Python - Copie.py", line 17, in <module>
f.write('\n'.join(li))
ValueError: I/O operation on closed file
0
zograme Messages postés 23 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 1 mars 2011
1 mars 2011 à 19:13
Code =

with open('J:\KARAFUN\Jekyll & Hyde - Bring On The Men - 34486 - ld.txt','r+') as f:
li = f.readlines()

longueur_max = 26

for i in xrange(len(li)-1,-1,-1):
line = li[i].rstrip()
decoup = []
while len(line)>longueur_max:
x = line[0:longueur_max].rfind(' ')
decoup.append(line[0:x])
line = line[x+1:]
decoup.append(line)
li[i:i+1] = decoup

f.seek(0,0)
f.write('\n'.join(li))
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Reivax962 Messages postés 3671 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021 1 011
1 mars 2011 à 14:21
Bonjour,

Oui, plein d'idées !
Mais il faudrait déjà commencer par nous dire en quoi tu programmes...

Xavier
0
zograme Messages postés 23 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 1 mars 2011
Modifié par zograme le 1/03/2011 à 14:26
Bonjour Reivax,

Tu devineras sans doute que si je demande quelque chose d'aussi simple, c'est que je ne programme pas vraiment :)

L'idéal ce serait de pouvoir le faire en batch, en lots si possible... Après, je suis ouvert à tout, sachant que mon niveau est au ras des pâquerettes...
0
Reivax962 Messages postés 3671 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021 1 011
1 mars 2011 à 14:40
OK.
Alors pour commencer, sous quelle forme se présente le texte que tu veux traiter ?
0
zograme Messages postés 23 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 1 mars 2011
1 mars 2011 à 15:18
C'est un fichier .txt tout bête, encodé en ANSI à priori (je sais pas trop comment le vérifier...). Ce sont des paroles de chansons, et pour la mise en page, j'ai besoin de ne pas dépasser une certaine longueur de phrases, disons 240 pixels. Sinon, on peut considérer un retour tous les 4-5 mots, mais c très aléatoire...
0
zograme Messages postés 23 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 1 mars 2011
Modifié par zograme le 1/03/2011 à 15:54
Ben en fait, je n'ai pas vraiment d'idée sur comment faire... :P

Je perds un temps dingue à tout découper à la main, et je me disais qu'il devait sûrement y avoir une fonction toute conne, du genre en batch ou autre, qui permette de le faire automatiquement.
0
zograme Messages postés 23 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 1 mars 2011
1 mars 2011 à 16:18
Je demandais en pensant que ça devait se faire assez facilement. Maintenant de là à payer 100 balles pour quelque chose vite fait...
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
1 mars 2011 à 16:39
Bonjour,

Connais tu et pratiques tu un langage de programmation ou non ?

Veux tu éventuellement te mettre à un langage pour faire ce que tu veux, si c'est nécessaire ?

ca peut se faire en une demie-heure, là tout de suite. Et sans euros
0
zograme Messages postés 23 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 1 mars 2011
1 mars 2011 à 16:43
Salut Heyquem,

J'ai fait un peu de python et de ruby. Mais très très vite fait. J'ai fait mumuse avec le batch aussi.

Si tu peux me guider, me donner les pistes à suivre, ce serait très sympa de ta part.
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
1 mars 2011 à 16:44
ben si tu as fait du python, on va faire ça en deux temps trois mouvements...
python est installé sur ta machine ?
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
1 mars 2011 à 16:46
quel est le chemin de ton fichier que tu veux exploiter ?

donne, stp, le contenu du fichier

si tu préfères tu peux me l'envoyer à cette adresse: heyquem@gmail.com
0
zograme Messages postés 23 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 1 mars 2011
1 mars 2011 à 16:45
Je m'en occupe de suite.
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
1 mars 2011 à 16:51
oui ?
de quoi donc ?
je surveille où ? ici ou dans mon email ?
0
zograme Messages postés 23 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 1 mars 2011
1 mars 2011 à 16:51
Je t'ai envoyé un mail.
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
1 mars 2011 à 16:52
OK. J'ai.
Il faut dire ce que tu veux faire plus précisément
0
zograme Messages postés 23 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 1 mars 2011
1 mars 2011 à 16:53
En gros, les phrases sont trop longues. Vis à vis de la mise en page, je voudrais découper celles-ci selon une certaine longueur, avec des retours à la ligne.
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
1 mars 2011 à 16:53
Il y a des slashes pkacés à des endroits erratiques. C'est normal ?
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
1 mars 2011 à 18:06
Soit dit en passant, ta question était mal formulée. ce n'est pas de la découpe de phrases que tu voulais faire mais de la découpe de lignes.
Je croyais au départ que tu voulais découper des phrases longues en phrases plus petites, gardant un sens. Mais justement avec cette nécessité de prendre en compte la signification d'une phrase, la découpe serait extrèmement plus difficile.

Il y a une bibliothèque qui s'occupe de texte au point de vue sémantique: lxml
0
zograme Messages postés 23 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 1 mars 2011
1 mars 2011 à 18:12
C'est vrai que je ne savais pas trop comment formuler ma question. Disons que je suis aussi parti sur quelque chose de simple, pour ne pas trop jouer les boulets.

Au passage, j'ai essayé de mettre un *.txt pour traiter le répertoire en entier, mais ca n'a pas l'air de lui plaire. Aurais tu une idée?
0
zograme Messages postés 23 Date d'inscription samedi 30 août 2008 Statut Membre Dernière intervention 1 mars 2011
1 mars 2011 à 18:43
En tous cas, merci infiniment pour ton aide, ça marche super bien. Ça a l'air vraiment bien foutu le python... :)
0
malaik5 Messages postés 258 Date d'inscription vendredi 20 novembre 2009 Statut Membre Dernière intervention 28 novembre 2013 33
1 mars 2011 à 15:51
ok,
donne nous le bout de programme que tu fais et là ou tu bloques, et on pourra te faire des commentaires pour t'aider
-1
malaik5 Messages postés 258 Date d'inscription vendredi 20 novembre 2009 Statut Membre Dernière intervention 28 novembre 2013 33
1 mars 2011 à 15:57
ok,
si tu veux pour 100euros je te fais un truc vite fait qui fait ça,
sinon il faut se mettre dans la programmation
-1