[Python] récupérer une série de caractère

Bonjour,

Voilà je souhaiterais récupérer dans un fichier texte une série de chffres du type :

276276276276277277277277277277277277278278278278278278278278278278278278278

278278278279279279279272272272272275275275275275275275275275275275275275275

275275275275275275275275275275274274274274266266266266266266266266266266266

266266266266266266266266266266266266266267267267267255255255255256256256256

256256256256256256256256256256256256256256256256256256256256250250250250250

250250250250250250250250250250250250250250250250250250250251251251251250250

250250247247247247247247247247247247247247247247247247248248248248245245245

245248248248248248248248248248248248248248248248248248248248248248248248248

248248248248246246246246246246246246246246246246246246246246246246246246246

246246246246246246246247247247247246246246246246246246246246246246246246246

246246246246246246247247247247244244244244244244244244244244244244244244244

244244244244244244244244244244244244244 lat = -89.5

dans mon fichier texte j'ai une centaine de série de ce type. ce sont en fait des coordonnées géographiques.
ce sont des séries de 864 caractères. Je voudrais les récupérer (sans le lat = 89.5)
je me suis dis qu'il y'avait surement un moyen pour définir ma variable comme une série de chiffres de 864 caractères. C'est a dire en bref "récupères moi l'ensemble des séries de 864 caractères et copie les dans un nouveau fichier.

merci a vous.
Configuration: Linux
Firefox 3.0.13

9 réponses

  1. En même temps, écrit comme ça, r2 matche aussi les lignes de r1, donc faut faire bien attention que le test de r1 se fasse avant le test r2 sinon certains caracères seront dupliqués. Ou bien affiner r1 et r2 pour inclure début de ligne et fin de ligne (avec ^ et $, cf doc de python) comme ça on est sûr :)
    Quel b*** ton truc :D
    1. Chez moi ce code fonctionne en faisant un copier/coller des données que tu as posté. Voici une version annotée du code, adapte le à ton fichier. (Cependant, il y a probablement plus mieux, je ne suis pas expert...)
      J'ai remplacé la regexp1 en enlevant le tiret bizarre qui n'est peut-être pas présent dans ton fichier d'origine mais a été ajouté par le forum pour tronquer la ligne.

      # -*- coding: iso-8859-1 -*-
      
      # on importe le module permettant de manipuler les expressions régulières
      import re
      
      FICHIER_A_LIRE = "texte1.txt"
      FICHIER_A_ECRIRE = "texte2.txt"
      
      # regexp 1 : 
      # \s: espace
      # \d{75}: suite de 75 chiffres consécutifs
      # les parenthèses sur (\d{75}) servent à délimiter le groupe
      # qui sera utilisé par la suite pour formatter la chaîne de sortie.
      r1 = re.compile( r"\s(\d{75})" )
      # regexp 2 :
      # \d{39}: suite de 39 chiffres consécutifs. Idem pour les parenthèses, elles
      # servent à délimiter un groupe.
      # cette regexp contient les derniers caractères des coordonées (juste avant le
      # alt = ... ) Elle permet donc de délimiter les différentes coordonnées.
      r2 = re.compile( r"\s(\d{39})" )
      
      # ouverture du fichier en mode lecture
      f_lire = open( FICHIER_A_LIRE, 'r' )
      
      # ouverture du fichier en mode écriture
      f_ecrire = open( FICHIER_A_ECRIRE, 'w' )
      
      # chaîne de caractères pour contenir la coordonnée à écrire dans le fichier
      s = ''
      # compteur utilisé pour comptabiliser le nombre de coordonnées écrites 
      # dans le fichier de sortie
      i = 0
      
      # boucle infinie
      while True:
          # lecture d'une ligne dans le fichier
          ligne = f_lire.readline()
          # si la chaîne renvoyée est nulle, on a atteint la fin du fichier...
          if ligne == '':
              # ... on a fini le traitement, on sort donc de la boucle
              break
          # on cherche regexp1 dans la ligne extraite
          m = r1.search( ligne )
          # si la regexp1 a été trouvée...
          if m:
              # ... on formatte la chaîne en concaténant la chaîne existante avec 
              # les caractères des coordonnées définis grâce au groupe entre 
              # parenthèses de la regexp. 
              # on se débarasse ainsi des espaces de début de ligne.
              s = s + m.group(1)
          # la regexp1 n'a pas été trouvée dans la ligne ...
          else:
              # ... on cherche la regexp2
              m = r2.search( ligne )
              # si elle est trouvée ...
              if m:
                  # on formatte la chaîne avec les caractères des coordonées
                  # définis dans le groupe entre parenthèses (on se débarasse de
                  # l'espace du début de ligne)
                  s = s + m.group(1)
                  # si cette regexp est rencontrée, cela signifie que l'on a atteint
                  # la fin d'une coordonnée. On écrit donc la chaîne obtenue dans
                  # le fichier de sortie.
                  f_ecrire.write( s )
                  # on incrémente le compteur
                  i = i + 1
                  # on réinitialise la chaîne par un saut de ligne pour débuter
                  # la coordonnée suivante.
                  s = '\n'
          # on boucle pour passer à la ligne suivante de FICHIER_A_LIRE.
      
      # on est sorti de la boucle, on a atteint la fin du fichier à lire,
      # on ferme nos fichiers.
      f_lire.close()
      f_ecrire.close()
      # on affiche le résultat du compteur.
      print i, "coordonnées écrites."
      


      D'après les résultats que tu as donné, la regexp1 ne semblait pas matcher. C'est cette ligne là qui est donc en cause :
      r1 = re.compile( r"\s(\d{60})\xAD(\d{15})" )


      Et biensûre :
      https://docs.python.org/3/library/re.html
      1. Et ça, ça donne quoi ?
        import re
        
        FICHIER_A_LIRE = "texte1.txt"
        FICHIER_A_ECRIRE = "texte2.txt"
        
        r1 = re.compile( r"\s(\d{60})\xAD(\d{15})" )
        r2 = re.compile( r"\s(\d{39})" )
        f_lire = open( FICHIER_A_LIRE, 'r' )
        f_ecrire = open( FICHIER_A_ECRIRE, 'w' )
        s = ''
        i = 0
        
        while True:
            ligne = f_lire.readline()
            if ligne == '':
                break
            m = r1.search( ligne )
            if m:
                s = s + m.group(1) + m.group(2)
            else:
                m = r2.search( ligne )
                if m:
                    s = s + m.group(1)
                    f_ecrire.write( s )
                    i = i + 1
                    s = '\n'
                
        f_lire.close()
        f_ecrire.close()
        print i, "coordonnees ecrites"
        

        Gaffe, le tiret dans les coordonnées est rendu par un shy en HTML. Ce n'est pas le même tiret que les moins par exemple (d'où le \xAD dans r1). Chez moi ce code marche si je fait un copier/coller des données que tu as posté dans un fichier.
        1. Salut Vimkiller....désolé pour hier soir, c'était session délestage (coupure de courant), j'ai pas eu le temps de répondre et tout et tout...

          Je viens de tester le nouveau code, mais en fait chez moi, ça découpe les données.

          Regarde le premier paragraphe c'est le fichier résultat, et le second le fichier d'origine.
          ON remarque qu'il conserve l'enchainement des lignes, mais il tronque une partie des données....GGrrrrr

          268268268268268268268268268268268268268
          268268268268268268268268268268268268268
          268268268268268268268268268268268268268
          268268268268268268268268267267267267267

          268268268268268268268268268268268268268268268268268268268268268268268268268

          268268268268268268268268268268268268268268268268268268268268268268268268268

          268268268268268268268268268268268268268268268268268268268268268268268268268

          268268268268268268268268267267267267267267267267267267267267267267267267268

          Sur le nouveau code j'ai vu que tu avais rajouté pas mal de choses, dont :

          r1 = re.compile( r"\s(\d{60})\xAD(\d{15})" )
          r2 = re.compile( r"\s(\d{39})" )

          r = re.compile(r"\d{25}" ) quelle est la différence avec un le nouveau r"\s(\d{60})\xAD(\d{15})" ).
          ça se complique un peu, du coup j'ai un peu de mal à suivre....
      2. arfff//// au lieu de conserver la mise en page il a vraiment tout modifier...

        je retente :

        Day:   1 Jan  1, 2000    EP/TOMS CORRECTED OZONE GEN:07.165 V8 ALECT: 11:17 AM 
        
         Longitudes:  288 bins centered on 179.375 W to 179.375 E  (1.25 degree steps)  
        
         Latitudes :  180 bins centered on  89.5   S to  89.5   N  (1.00 degree steps)  
        
         276276276276277277277277277277277277278278278278278278278278278278278278278
        
         278278278279279279279272272272272275275275275275275275275275275275275275275
        
         275275275275275275275275275275274274274274266266266266266266266266266266266
        
         266266266266266266266266266266266266266267267267267255255255255256256256256
        
         256256256256256256256256256256256256256256256256256256256256250250250250250
        
         250250250250250250250250250250250250250250250250250250250251251251251250250
        
         250250247247247247247247247247247247247247247247247247248248248248245245245
        
         245248248248248248248248248248248248248248248248248248248248248248248248248
        
         248248248248246246246246246246246246246246246246246246246246246246246246246
        
         246246246246246246246247247247247246246246246246246246246246246246246246246
        
         246246246246246246247247247247244244244244244244244244244244244244244244244
        
         244244244244244244244244244244244244244   lat =  -89.5  
        
         279279279279279279279279279279279279279279279279281281281281280280280280280
        
         280280280280280280280280280280280280280280280281281281281276276276276276276
        
         276276274274274274274274274274274274274274275275275275267267267267267267267
        
         267264264264264259259259259259259259259258258258258257257257257256256256256
        
         247247247247247247247247247247247247248248248248248248248248247247247247247
        
         247247247247247247247247247247247247247247247247247247247247247247247246246
        
         246246246246246246248248248248247247247247247247247247248248248248248248248
        
         248248248248248247247247247247247247247247247247247250250250250250250250250
        
         250250250250247247247247249249249249249249249249249249249249249249249249248
        
         248248248249249249249249249249249249249249249247247247247247247247247246246
        
         246246246246246246246246246246246246246246245245245245245245245245246246246
        
         246246246246246246246246246246246246246   lat =  -88.5
        
         283283283283285285285285287287287287285285285285285285285285287287287287287
        
         287287287283283283283283283283283283283283283283283283283280280280280278278
        
         278278278278278278274274274274269269269269269269269269269269269269267267267
        
         267266266266266249249249249249249249249249249249249247247247247246246246246
        
         243243243243242242242242242242242242243243243243243243243243243243243243242
        
         242242242243243243243244244244244244244244244244244244244244244244244245245
        
         245245247247247247247247247247244244244244245245245245248248248248246246246
        
         246245245245245246246246246246246246246245245245245245245245245249249249249
        
         247247247247250250250250251251251251253253253253253253253253253253253253253
        
         253253253253253253253254254254254255255255255252252252252254254254254255255
        
         255255255255255255250250250250250250250250250250250250249249249249249249249
        
         249245245245245246246246246247247247247   lat =  -87.5
        1. et voilà la bestiole !!!

          Day:   1 Jan  1, 2000    EP/TOMS CORRECTED OZONE GEN:07.165 V8 ALECT: 11:17 AM 
          
           Longitudes:  288 bins centered on 179.375 W to 179.375 E  (1.25 degree steps)  
          
           Latitudes :  180 bins centered on  89.5   S to  89.5   N  (1.00 degree steps)  
          
           276276276276277277277277277277277277278278278278278278278278278278278278278
          
           278278278279279279279272272272272275275275275275275275275275275275275275275
          
           275275275275275275275275275275274274274274266266266266266266266266266266266
          
           266266266266266266266266266266266266266267267267267255255255255256256256256
          
           256256256256256256256256256256256256256256256256256256256256250250250250250
          
           250250250250250250250250250250250250250250250250250250250251251251251250250
          
           250250247247247247247247247247247247247247247247247247248248248248245245245
          
           245248248248248248248248248248248248248248248248248248248248248248248248248
          
           248248248248246246246246246246246246246246246246246246246246246246246246246
          
           246246246246246246246247247247247246246246246246246246246246246246246246246
          
           246246246246246246247247247247244244244244244244244244244244244244244244244
          
           244244244244244244244244244244244244244   lat =  -89.5  
          
           279279279279279279279279279279279279279279279279281281281281280280280280280
          
           280280280280280280280280280280280280280280280281281281281276276276276276276
          
           276276274274274274274274274274274274274274275275275275267267267267267267267
          
           267264264264264259259259259259259259259258258258258257257257257256256256256
          
           247247247247247247247247247247247247248248248248248248248248247247247247247
          
           247247247247247247247247247247247247247247247247247247247247247247247246246
          
           246246246246246246248248248248247247247247247247247247248248248248248248248
          
           248248248248248247247247247247247247247247247247247250250250250250250250250
          
           250250250250247247247247249249249249249249249249249249249249249249249249248
          
           248248248249249249249249249249249249249249249247247247247247247247247246246
          
           246246246246246246246246246246246246246246245245245245245245245245246246246
          
           246246246246246246246246246246246246246   lat =  -88.5
          
           283283283283285285285285287287287287285285285285285285285285287287287287287
          
           287287287283283283283283283283283283283283283283283283283280280280280278278
          
           278278278278278278274274274274269269269269269269269269269269269269267267267
          
           267266266266266249249249249249249249249249249249249247247247247246246246246
          
           243243243243242242242242242242242242243243243243243243243243243243243243242
          
           242242242243243243243244244244244244244244244244244244244244244244244245245
          
           245245247247247247247247247247244244244244245245245245248248248248246246246
          
           246245245245245246246246246246246246246245245245245245245245245249249249249
          
           247247247247250250250250251251251251253253253253253253253253253253253253253
          
           253253253253253253253254254254254255255255255252252252252254254254254255255
          
           255255255255255255250250250250250250250250250250250250249249249249249249249
          
           249245245245245246246246246247247247247   lat =  -87.5
          1. Arf, c'était trop beau ;)
            Dans ton post, les espaces avant n'apparaîssent pas et on a une ligne vide entre chaque ligne.
            Pourrais-tu reposter 2 blocs consécutifs complets (avec le lat aussi) en utilisant "conserver la mise en forme du texte sélectionné" histoire qu'on y voit un peu plus clair.
            1. bonsoir;

              je viens de tester ton code, il marche et m'aide bien ...merci bcp.
              mais.....et oui/ parce qu'il y'a tjrs un mais.
              en fait :

              - r = re.compile(r"\d{864}" ) # récupère les chaines de caractères de 864.

              Par contre, en testant avec ton code je me suis rendu compte que les choses étaient un peu plus compliquées.
              en fait je pensais que chaque série de données étaient en un seul bloque, mais en fait a chaque retour à la ligne il y'a un espace entre la marge et le premier chiffre. ce qui fait qu'avec 864 ça ne marchait pas. j'avais bien mon fichier_ a_écrire qui était créé mais rien dedans, tout simplement parce qu'il ne trouvait pas de suite de caractère de 864.
              en fait par série cela me donne 11 lignes avec une suite de 75 caract et une ligne qui fini le bloc de 13 caractères/

              je te met ci joint un exemple avec le premier bloc en entier:

              276276276276277277277277277277277277278278278278278278278278278278278278278

              278278278279279279279272272272272275275275275275275275275275275275275275275

              275275275275275275275275275275274274274274266266266266266266266266266266266

              266266266266266266266266266266266266266267267267267255255255255256256256256

              256256256256256256256256256256256256256256256256256256256256250250250250250

              250250250250250250250250250250250250250250250250250250250251251251251250250

              250250247247247247247247247247247247247247247247247247248248248248245245245

              245248248248248248248248248248248248248248248248248248248248248248248248248

              248248248248246246246246246246246246246246246246246246246246246246246246246

              246246246246246246246247247247247246246246246246246246246246246246246246246

              246246246246246246247247247247244244244244244244244244244244244244244244244

              244244244244244244244244244244244244244

              du coup, là niveau méthode je bloque un peu, si je peux dire !!! tu vois mes blocs de données ne commencent pas contre la marge. donc comme je te disais 11 lignes de 75 car et une dernière de 30car.

              et merci encore.
              1. ahh...

                merci beaucoup de me répondre..je commençais a désespérer face à ces codes;
                il est 20h00 chez moi...je vais donc tester tout ça demain, mais au moins je rentre chez moi avec une note optimiste !!!
                merci bcp...
                1. Réponse Quick & Dirty :)

                  import re
                  
                  FICHIER_A_PARSER = "texte1.txt"
                  FICHIER_A_ECRIRE = "texte2.txt"
                  NOUVELLE_LIGNE = '\n'
                  
                  r = re.compile(r"\d{864}" )
                  f = open( FICHIER_A_PARSER, 'r' )
                  s = f.read()
                  f.close()
                  occurences = r.findall( s )
                  f = open( FICHIER_A_ECRIRE, 'w' )
                  for coord in occurences:
                      f.write( coord )
                      f.write( NOUVELLE_LIGNE )
                  f.close()