2010-03-18 5 views
0

J'ai un grand fichier texte, qui a des sauts de ligne à la colonne 80 en raison de la largeur de la console. La plupart des lignes du fichier texte ne comportent pas 80 caractères et ne sont pas affectées par le saut de ligne. En pseudocode, voici ce que je veux:Supprimer le saut de ligne à une position spécifique dans le fichier texte

  • Itérer à travers les lignes dans le fichier
  • Si la ligne correspond à ce modèle regex: (. {80})^\ n (+).
    • Remplacer cette ligne avec une nouvelle chaîne composée de match.group (1) et match.group (2). Supprimez simplement le changement de ligne de cette ligne.
  • Si la ligne ne correspond pas à la regex, passez!

Peut-être que je n'ai pas besoin de regex pour le faire?

Répondre

1
f=open("file") 
for line in f: 
    if len(line)==81: 
     n=f.next() 
     line=line.rstrip()+n 
    print line.rstrip() 
f.close() 
+1

Attention, vous ne gérez pas StopIteration dans votre appel à f.next(), donc ce code échouera si la dernière ligne a 81 caractères. –

+0

et si une ligne est très longue et enroulée plusieurs fois, alors seulement un saut de ligne sur deux sera supprimé. – tux21b

1

est ici un code qui devrait à l'astuce

def remove_linebreaks(textfile, position=81): 
    """ 
    textfile : an file opened in 'r' mode 
    position : the index on a line at which \n must be removed 

    return a string with the \n at position removed 
    """ 
    fixed_lines = [] 
    for line in textfile: 
     if len(line) == position: 
      line = line[:position] 
     fixed_lines.append(line) 
    return ''.join(fixed_lines) 

Notez que par rapport à votre code pseudo, ce fusionnera un certain nombre de lignes pliées consécutives.

0

Voici un exemple d'utilisation d'expressions régulières pour archiver ceci. Mais les expressions régulières ne sont pas la meilleure solution partout et dans ce cas, je pense que l'utilisation d'expressions régulières n'est pas plus efficace. Quoi qu'il en soit, voici la solution:

text = re.sub(r'(?<=^.{80})\n', '', text) 

Vous pouvez également utiliser l'expression régulière lorsque vous appelez re.sub avec un appelable:

text = re.sub(r'^(.{80})\n(.+)', lambda m: m.group(1)+m.group(2), text) 
1

Considérez ceci.

def merge_lines(line_iter): 
    buffer = '' 
    for line in line_iter: 
     if len(line) <= 80: 
      yield buffer + line 
      buffer= '' 
     else: 
      buffer += line[:-1] # remove '\n' 

with open('myFile','r') as source: 
    with open('copy of myFile','w') as destination: 
     for line in merge_lines(source): 
      destination.write(line) 

Je trouve qu'une fonction génératrice explicite rend beaucoup plus facile à tester et déboguer la logique essentielle du script sans avoir à créer des systèmes de fichiers simulacres ou faire beaucoup de fantaisie et de configuration teardown pour les tests.

+0

Cela semble intéressant! Je vais essayer ça. – user265978

+0

Attention, votre code ne gère pas correctement 2 lignes consécutives de plus de 80 caractères. –

+0

@gurney alex: Merci. Fixé. –

Questions connexes