2009-08-08 8 views
18

Sto familiarizzando con Python e sto creando problemi per aiutarmi ad apprendere i dettagli della lingua. Il mio prossimo problema è il seguente:Problema Python/Regex semplice: Rimozione di tutte le nuove linee da un file

Ho copiato e incollato un'enorme quantità di testo da Internet, ma il copia e incolla ha aggiunto diverse nuove righe per spezzare l'enorme stringa. Desidero rimuovere tutti questi programmi e restituire la stringa in un gigantesco gruppo di caratteri. Questo è ovviamente un lavoro per regex (credo), e l'analisi del file e la rimozione di tutte le istanze del carattere di nuova riga suona come se funzionasse, ma non sembra che vada per il meglio.

C'è un modo semplice per andare su questo? Sembra piuttosto semplice.

risposta

28

Le due alternative principali: leggere tutto in una singola stringa e rimuovere nuove righe:

clean = open('thefile.txt').read().replace('\n', '') 

o, leggere riga per riga, rimuovendo la nuova riga che termina ogni riga, e unirsi di nuovo:

clean = ''.join(l[:-1] for l in open('thefile.txt')) 

La prima alternativa è probabilmente più veloce, ma, come sempre, vi consigliamo caldamente di misurare la velocità (ad esempio, utilizzare python -mtimeit) in caso di vostra speci interesse fic, piuttosto che presumere che tu sappia come saranno le prestazioni. I RE sono probabilmente più lenti, ma, ancora una volta: non indovinare, MISURA!

Quindi, ecco alcuni numeri per un file di testo specifica sul mio portatile:

$ python -mtimeit -s"import re" "re.sub('\n','',open('AV1611Bible.txt').read())" 
10 loops, best of 3: 53.9 msec per loop 
$ python -mtimeit "''.join(l[:-1] for l in open('AV1611Bible.txt'))" 
10 loops, best of 3: 51.3 msec per loop 
$ python -mtimeit "open('AV1611Bible.txt').read().replace('\n', '')" 
10 loops, best of 3: 35.1 msec per loop 

Il file è una versione del KJ Bibbia, scaricato e decompresso da here (io credo che sia importante eseguire tali misurazioni su un file facilmente recuperabile, così altri possono facilmente riprodurli!).

Ovviamente, alcuni millisecondi più o meno su un file di 4,3 MB, 34000 righe, potrebbero non essere importanti per voi in un modo o nell'altro; ma siccome l'approccio più veloce è anche il più semplice (lontano da un evento insolito, specialmente in Python ;-), penso che sia una buona raccomandazione.

+0

E riguardo string.strip()? es. python -mtimeit "'' .join (l.strip() per l in open ('AV1611Bible.txt'))" – hughdbrown

+0

Questo ha una semantica diversa, poiché rimuove gli spazi iniziali e finali, che NON fa parte delle specifiche (anche rstrip rimuoverà comunque gli spazi finali, di nuovo al di fuori delle specifiche). Ad ogni modo, entrambi sono molto più lenti di quelli che usano l [: - 1], di circa il 3%, ripetutamente. –

3
import re 
re.sub("\n", "", file-contents-here) 
+0

così ho intenzione di aprire manualmente il file, leggerlo carattere per carattere in una stringa, fare un sottotitolo e riscrivere il file carattere per carattere? – Chris

+0

o meglio ri.sub ("[\ n \ r] +", "", file-contents); –

+1

@Chris: 'open (fname) .read()' fornisce una stringa, dopo averlo filtrato puoi scriverlo come 'open (fname2, 'w'). Write (output_sting)'. Cosa significa esattamente carattere per carattere? – SilentGhost

8

Non vorrei usare un'espressione regolare per la semplice sostituzione a capo - userei string.replace(). Ecco uno script completo:

f = open('input.txt') 
contents = f.read() 
f.close() 
new_contents = contents.replace('\n', '') 
f = open('output.txt', 'w') 
f.write(new_contents) 
f.close() 
+1

Bello, la nuova riga è racchiusa tra virgolette singole. Questo importa in Python? –

+0

no. – SilentGhost

+1

Le stringhe possono usare virgolette singole o doppie in Python: sono equivalenti. – RichieHindle

2

So che questo è un problema di apprendimento Python, ma se si sta provando a farlo dalla riga di comando, non è necessario scrivere uno script Python. Qui ci sono un paio di altri modi:

cat $FILE | tr -d '\n' 

awk '{printf("%s", $0)}' $FILE 

Nessuno di questi ha per leggere l'intero file in memoria, quindi se hai un file enormi per elaborare, che potrebbe essere migliore rispetto alle soluzioni fornite pitone.

+0

Non python, ma +1 per menzionare il problema dei file di grandi dimensioni, che è sempre utile tenere a mente. – Pinochle

+0

non serve gatto per il codice tr. tr -d '\ n' ghostdog74

0

Vecchia domanda, ma poiché era nei miei risultati di ricerca per una query simile, e nessuno ha menzionato le funzioni di stringa python strip() || lstrip() || rstrip(), lo aggiungerò per i posteri (e chiunque preferisca non usare re quando non necessario):

old = open('infile.txt') 
new = open('outfile.txt', 'w') 
stripped = [line.strip() for line in old] 
old.close() 
new.write("".join(stripped)) 
new.close() 
+0

Il non uso di 'strip()' e 'lstrip()' è stato discusso nei commenti su Martelli [risposta] (http://stackoverflow.com/a/1249740/355230). – martineau

Problemi correlati