[Help] Découper des textes en groupes de mots
heyquem Messages postés 808 Statut Membre -
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?
18 réponses
Le sujet concerne le découpage automatique des phrases d'un texte afin que chaque élément ne dépasse pas une longueur maximale configurée, afin d'obtenir des phrases compactes adaptées à des contraintes d'affichage. Plusieurs solutions évoquent l'usage de Python pour découper le texte selon longueur_max, en privilégiant les espaces comme séparateurs et en enregistrant le résultat dans un fichier distinct pour éviter d'écraser l'original. Des ajustements traitent les cas sans espace avant la limite et proposent des variantes comme le parcours de dossiers via os.walk et la sauvegarde dans un fichier secondaire.
-
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 lufrom 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...:)-
-
-
-
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... -
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 '------------------------------------------'
-
-
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)-
-
-
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é
-
-
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.-
-
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
-
-
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))-
-
-
-
-
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))
-
-
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question -
Bonjour,
Oui, plein d'idées !
Mais il faudrait déjà commencer par nous dire en quoi tu programmes...
Xavier -
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... -
OK.
Alors pour commencer, sous quelle forme se présente le texte que tu veux traiter ? -
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...
-
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. -
Je demandais en pensant que ça devait se faire assez facilement. Maintenant de là à payer 100 balles pour quelque chose vite fait...
-
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 -
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. -
Je m'en occupe de suite.
-
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 -
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? -
En tous cas, merci infiniment pour ton aide, ça marche super bien. Ça a l'air vraiment bien foutu le python... :)
-
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 -
ok,
si tu veux pour 100euros je te fais un truc vite fait qui fait ça,
sinon il faut se mettre dans la programmation