2009-08-08 22 views
18

Me estoy familiarizando con Python y estoy creando problemas para ayudarme a aprender los entresijos del idioma. Mi próximo problema es el siguiente:Problema simple de Python/Regex: Eliminar todas las líneas nuevas de un archivo

He copiado y pegado una gran cantidad de texto de Internet, pero el copiar y pegar agregó varias líneas nuevas para romper la enorme cadena. Deseo eliminar programáticamente todos estos y devolver la cadena en una burbuja gigante de caracteres. Obviamente, este es un trabajo para regex (creo), y analizar el archivo y eliminar todas las instancias del carácter de nueva línea parece que funcionaría, pero parece que no me está yendo muy bien.

¿Hay una manera fácil de hacerlo? Parece bastante simple.

Respuesta

28

Las dos alternativas principales: leer todo en una sola cuerda y eliminar saltos de línea:

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

o, leer línea por línea, eliminando la nueva línea que termina cada línea, y unirlo de nuevo:

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

La primera alternativa es probablemente más rápido, pero, como siempre, recomiendo encarecidamente que miden la velocidad (por ejemplo, utilizar python -mtimeit) en los casos de su especificidad interés de fic, en lugar de solo asumir que usted sabe cómo será el rendimiento. Los RE son probablemente más lentos, pero, de nuevo: ¡no adivinen, MIDA!

Así que aquí están algunos números para un archivo de texto específico en mi portátil:

$ 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 

El archivo es una versión de la Biblia KJ, descargado y descomprimido de here (yo creo que es importante realizar tales mediciones en un archivo fácil de obtener, para que otros puedan reproducirlos fácilmente!).

Por supuesto, unos pocos milisegundos más o menos en un archivo de 4.3 MB, 34,000 líneas, pueden no importar mucho para usted de una forma u otra; pero como el enfoque más rápido también es el más simple (lejos de ser algo inusual, especialmente en Python ;-), creo que es una muy buena recomendación.

+0

¿Qué tal string.strip()? es decir, python -mtimeit "'' .join (l.strip() para l en abierto ('AV1611Bible.txt'))" – hughdbrown

+0

Eso tiene una semántica diferente, ya que eliminaría los espacios iniciales y finales, lo cual NO es parte de las especificaciones (incluso rstrip aún eliminaría los espacios finales, nuevamente fuera de las especificaciones). De todos modos, ambos son muy ligeramente más lentos que el uso de l [: - 1], en alrededor del 3%, de forma repetitiva. –

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

así que voy a tener que abrir manualmente el archivo, leer el carácter para el carácter en una cadena, hacer un sub y escribir de nuevo el carácter carácter por carácter? – Chris

+0

o mejor re.sub ("[\ n \ r] +", "", contenido del archivo); –

+1

@Chris: 'open (fname) .read()' le da una cadena, después de filtrar puede escribirlo como 'open (fname2, 'w'). Write (output_sting)'. ¿Qué significa exactamente carácter por personaje? – SilentGhost

8

yo no usaría una expresión regular para la simple sustitución de los saltos de línea - que haría uso de string.replace(). Aquí hay un guión 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

Agradable, la nueva línea está dentro de comillas simples. ¿Eso importa en Python? –

+0

no. – SilentGhost

+1

Las cadenas pueden usar comillas simples o dobles en Python, son equivalentes. – RichieHindle

2

Sé que este es un problema de aprendizaje de python, pero si alguna vez intentas hacer esto desde la línea de comandos, no es necesario escribir un script de python. Aquí hay un par de otras maneras:

cat $FILE | tr -d '\n' 

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

Ninguno de ellos tiene que leer todo el archivo en la memoria, por lo que si usted tiene un archivo enorme para procesar, que podría ser mejor que las soluciones proporcionadas pitón.

+0

No python, pero +1 por mencionar el problema del archivo grande, que siempre es bueno tener en cuenta. – Pinochle

+0

no necesita cat para el código tr. tr -d '\ n' ghostdog74

0

Pregunta anterior, pero como estaba en mis resultados de búsqueda para una consulta similar, y nadie ha mencionado las funciones de cadena de pitón strip() || lstrip() || rstrip(), solo agregaré eso para la posteridad (y cualquiera que prefiera no usar re cuando no necesario):

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

La falta de uso de 'strip()' y 'lstrip()' _were_ se comenta en los comentarios sobre Martelli's [respuesta] (http://stackoverflow.com/a/1249740/355230) – martineau

Cuestiones relacionadas