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

zograme Messages postés 23 Date d'inscription   Statut Membre Dernière intervention   -  
heyquem Messages postés 808 Statut Membre -
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?

18 réponses

Résumé de la discussion

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.

Généré automatiquement par IA
sur la base des meilleures réponses
  1. heyquem Messages postés 808 Statut Membre 131
     
    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
    1. zograme Messages postés 23 Date d'inscription   Statut Membre Dernière intervention  
       
      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
    2. heyquem Messages postés 808 Statut Membre 131
       
      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
    3. zograme Messages postés 23 Date d'inscription   Statut Membre Dernière intervention  
       
      J'ai changé le c:\\contenant oui. Pourquoi \\ d'ailleurs?
      0
    4. zograme Messages postés 23 Date d'inscription   Statut Membre Dernière intervention  
       
      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
    5. heyquem Messages postés 808 Statut Membre 131
       
      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
  2. heyquem Messages postés 808 Statut Membre 131
     
    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
    1. zograme Messages postés 23 Date d'inscription   Statut Membre Dernière intervention  
       
      OK, super. Je teste ça de suite.
      0
    2. zograme Messages postés 23 Date d'inscription   Statut Membre Dernière intervention  
       
      Ç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
    3. heyquem Messages postés 808 Statut Membre 131
       
      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
  3. heyquem Messages postés 808 Statut Membre 131
     
    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
    1. zograme Messages postés 23 Date d'inscription   Statut Membre Dernière intervention  
       
      Super, je teste ça. Dsl pour ma lenteur, connexion internet à la Réunion. C'est pas le top ^^
      0
    2. heyquem Messages postés 808 Statut Membre 131
       
      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
  4. heyquem Messages postés 808 Statut Membre 131
     
    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
    1. zograme Messages postés 23 Date d'inscription   Statut Membre Dernière intervention  
       
      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
    2. heyquem Messages postés 808 Statut Membre 131
       
      ah ben non , non non , pas comme ça

      attends, je reviens , là

      je vais te faire ça
      0
    3. heyquem Messages postés 808 Statut Membre 131
       
      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
    4. zograme Messages postés 23 Date d'inscription   Statut Membre Dernière intervention  
       
      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
    5. zograme Messages postés 23 Date d'inscription   Statut Membre Dernière intervention  
       
      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
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. Reivax962 Messages postés 3742 Statut Membre 1 011
     
    Bonjour,

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

    Xavier
    0
  7. zograme Messages postés 23 Date d'inscription   Statut Membre Dernière intervention  
     
    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
  8. Reivax962 Messages postés 3742 Statut Membre 1 011
     
    OK.
    Alors pour commencer, sous quelle forme se présente le texte que tu veux traiter ?
    0
  9. zograme Messages postés 23 Date d'inscription   Statut Membre Dernière intervention  
     
    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
  10. zograme Messages postés 23 Date d'inscription   Statut Membre Dernière intervention  
     
    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
  11. zograme Messages postés 23 Date d'inscription   Statut Membre Dernière intervention  
     
    Je demandais en pensant que ça devait se faire assez facilement. Maintenant de là à payer 100 balles pour quelque chose vite fait...
    0
  12. heyquem Messages postés 808 Statut Membre 131
     
    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
  13. zograme Messages postés 23 Date d'inscription   Statut Membre Dernière intervention  
     
    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
    1. heyquem Messages postés 808 Statut Membre 131
       
      ben si tu as fait du python, on va faire ça en deux temps trois mouvements...
      python est installé sur ta machine ?
      0
    2. heyquem Messages postés 808 Statut Membre 131
       
      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
  14. zograme Messages postés 23 Date d'inscription   Statut Membre Dernière intervention  
     
    Je m'en occupe de suite.
    0
    1. heyquem Messages postés 808 Statut Membre 131
       
      oui ?
      de quoi donc ?
      je surveille où ? ici ou dans mon email ?
      0
    2. zograme Messages postés 23 Date d'inscription   Statut Membre Dernière intervention  
       
      Je t'ai envoyé un mail.
      0
    3. heyquem Messages postés 808 Statut Membre 131
       
      OK. J'ai.
      Il faut dire ce que tu veux faire plus précisément
      0
    4. zograme Messages postés 23 Date d'inscription   Statut Membre Dernière intervention  
       
      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
    5. heyquem Messages postés 808 Statut Membre 131
       
      Il y a des slashes pkacés à des endroits erratiques. C'est normal ?
      0
  15. heyquem Messages postés 808 Statut Membre 131
     
    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
  16. zograme Messages postés 23 Date d'inscription   Statut Membre Dernière intervention  
     
    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
  17. zograme Messages postés 23 Date d'inscription   Statut Membre Dernière intervention  
     
    En tous cas, merci infiniment pour ton aide, ça marche super bien. Ça a l'air vraiment bien foutu le python... :)
    0
  18. malaik5 Messages postés 259 Date d'inscription   Statut Membre Dernière intervention   33
     
    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
  19. malaik5 Messages postés 259 Date d'inscription   Statut Membre Dernière intervention   33
     
    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