¿Cómo puedo eliminar una nueva línea final en Python?

¿Cuál es el equivalente de Python de la función chomp de Perl, que elimina el último carácter de una cadena si es una nueva línea?

Pruebe el método rstrip() (consulte el documento Python 2 y Python 3 )

 >>> 'test string\n'.rstrip() 'test string' 

El método rstrip() Python rstrip() todos los tipos de espacios en blanco al final de manera predeterminada, no solo una nueva línea como Perl lo hace con chomp .

 >>> 'test string \n \r\n\n\r \n\n'.rstrip() 'test string' 

Para desnudar solo nuevas líneas:

 >>> 'test string \n \r\n\n\r \n\n'.rstrip('\n') 'test string \n \r\n\n\r ' 

También están los métodos lstrip() y strip() :

 >>> s = " \n\r\n \n abc def \n\r\n \n " >>> s.strip() 'abc def' >>> s.lstrip() 'abc def \n\r\n \n ' >>> s.rstrip() ' \n\r\n \n abc def' 

Y diría que la forma “pythonic” de obtener líneas sin caracteres de nueva línea final es splitlines ().

 >>> text = "line 1\nline 2\r\nline 3\nline 4" >>> text.splitlines() ['line 1', 'line 2', 'line 3', 'line 4'] 

La forma canónica de eliminar los caracteres de final de línea (EOL) es usar el método de cadena rstrip () para eliminar cualquier \ r o \ n. Aquí hay ejemplos de los caracteres EOL para Mac, Windows y Unix.

 >>> 'Mac EOL\r'.rstrip('\r\n') 'Mac EOL' >>> 'Windows EOL\r\n'.rstrip('\r\n') 'Windows EOL' >>> 'Unix EOL\n'.rstrip('\r\n') 'Unix EOL' 

Usar ‘\ r \ n’ como el parámetro a rstrip significa que eliminará cualquier combinación final de ‘\ r’ o ‘\ n’. Es por eso que funciona en los tres casos anteriores.

Este matiz importa en casos raros. Por ejemplo, una vez tuve que procesar un archivo de texto que contenía un mensaje HL7. El estándar HL7 requiere un ‘\ r’ al final como su carácter EOL. La máquina de Windows en la que estaba usando este mensaje había añadido su propio carácter ‘\ r \ n’ EOL. Por lo tanto, el final de cada línea parecía ‘\ r \ r \ n’. El uso de rstrip (‘\ r \ n’) hubiera eliminado todo el ‘\ r \ r \ n’, que no es lo que quería. En ese caso, simplemente corté los dos últimos caracteres en su lugar.

Tenga en cuenta que a diferencia de la función chomp de Perl, esto eliminará todos los caracteres especificados al final de la cadena, no solo uno:

 >>> "Hello\n\n\n".rstrip("\n") "Hello" 

Tenga en cuenta que rstrip no actúa exactamente como el chomp () de Perl porque no modifica la cadena. Es decir, en Perl:

 $x="a\n"; chomp $x 

resulta en $x siendo "a" .

pero en Python:

 x="a\n" x.rstrip() 

significará que el valor de x sigue siendo "a\n" . Incluso x=x.rstrip() no siempre da el mismo resultado, ya que elimina todos los espacios en blanco del final de la cadena, no solo una nueva línea como máximo.

Podría usar algo como esto:

 import os s = s.rstrip(os.linesep) 

Creo que el problema con rstrip("\n") es que probablemente querrá asegurarse de que el separador de línea sea portátil. (Se rumorea que algunos sistemas anticuados usan "\r\n" ). El otro problema es que rstrip eliminará los espacios en blanco repetidos. Esperemos que os.linesep contenga los caracteres correctos. Lo anterior funciona para mí.

Puede usar line = line.rstrip('\n') . Esto eliminará todas las líneas nuevas del final de la cadena, no solo una.

 s = s.rstrip() 

eliminará todas las líneas nuevas al final de la cadena s . La asignación es necesaria porque rstrip devuelve una nueva cadena en lugar de modificar la cadena original.

 "line 1\nline 2\r\n...".replace('\n', '').replace('\r', '') >>> 'line 1line 2...' 

o siempre podrías ponerte geekier con expresiones regulares 🙂

¡que te diviertas!

Esto replicaría exactamente el chomp de perl (menos el comportamiento en las matrices) para el terminador de línea “\ n”:

 def chomp(x): if x.endswith("\r\n"): return x[:-2] if x.endswith("\n") or x.endswith("\r"): return x[:-1] return x 

(Nota: no modifica la cadena ‘en su lugar’; no elimina los espacios en blanco al final; toma \ r \ n en la cuenta)

puedes usar la tira

 line = line.strip() 

manifestación:

 >>> "\n\n hello world \n\n".strip() 'hello world' 

Cuidado con "foo".rstrip(os.linesep) : Eso solo afectará a los caracteres de nueva línea de la plataforma donde se está ejecutando Python. Imagina que estás chimping las líneas de un archivo de Windows en Linux, por ejemplo:

 $ python Python 2.7.1 (r271:86832, Mar 18 2011, 09:09:48) [GCC 4.5.0 20100604 [gcc-4_5-branch revision 160292]] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import os, sys >>> sys.platform 'linux2' >>> "foo\r\n".rstrip(os.linesep) 'foo\r' >>> 

Use "foo".rstrip("\r\n") lugar, como Mike dice arriba.

Un ejemplo en la documentación de Python simplemente usa line.strip() .

La función chomp de Perl elimina una secuencia de salto de línea del final de una cadena solo si está realmente allí.

Aquí es cómo planeo hacer eso en Python, si el process es conceptualmente la función que necesito para hacer algo útil para cada línea de este archivo:

 import os sep_pos = -len(os.linesep) with open("file.txt") as f: for line in f: if line[sep_pos:] == os.linesep: line = line[:sep_pos] process(line) 

rstrip no hace lo mismo que chomp, en muchos niveles. Lea http://perldoc.perl.org/functions/chomp.html y vea que chomp es realmente complejo.

Sin embargo, mi punto principal es que chomp elimina como máximo 1 línea, mientras que rstrip eliminará tantas como sea posible.

Aquí puedes ver rstrip eliminando todas las nuevas líneas:

 >>> 'foo\n\n'.rstrip(os.linesep) 'foo' 

Una aproximación mucho más cercana del uso típico de Perl chomp se puede lograr con re.sub, como esto:

 >>> re.sub(os.linesep + r'\Z','','foo\n\n') 'foo\n' 

No programo en Python, pero encontré una sección de Preguntas frecuentes en python.org que promueve S.rstrip (“\ r \ n”) para python 2.2 o posterior.

 import re r_unwanted = re.compile("[\n\t\r]") r_unwanted.sub("", your_text) 

Solución alternativa para casos especiales:

Si el carácter de nueva línea es el último carácter (como es el caso con la mayoría de las entradas de archivos), entonces para cualquier elemento de la colección puede indexar lo siguiente:

 foobar= foobar[:-1] 

para cortar su personaje de nueva línea.

Si su pregunta es limpiar todos los saltos de línea en un objeto str de múltiples líneas (oldstr), puede dividirlo en una lista de acuerdo con el delimitador ‘\ n’ y luego unirla a una nueva str (newstr).

newstr = "".join(oldstr.split('\n'))

Parece que no hay un análogo perfecto para el chomp de Perl. En particular, rstrip no puede manejar delimitadores de nueva línea de varios caracteres como \r\n . Sin embargo, splitlines hace como se indica aquí . Siguiendo mi respuesta en una pregunta diferente, puede combinar las líneas de unión y división para eliminar / reemplazar todas las líneas nuevas de una cadena s :

 ''.join(s.splitlines()) 

Lo siguiente elimina exactamente una nueva línea final (como lo haría chomp, creo). Pasando True como el argumento de keepends a splitlines retiene los delimitadores. Luego, se vuelve a llamar a splitlines para eliminar los delimitadores solo en la última “línea”:

 def chomp(s): if len(s): lines = s.splitlines(True) last = lines.pop() return ''.join(lines + last.splitlines()) else: return '' 

Me parece conveniente poder obtener las líneas segmentadas a través del iterador, paralelamente a la forma en que se pueden obtener las líneas no segmentadas de un objeto de archivo. Puedes hacerlo con el siguiente código:

 def chomped_lines(it): return map(operator.methodcaller('rstrip', '\r\n'), it) 

Uso de la muestra:

 with open("file.txt") as infile: for line in chomped_lines(infile): process(line) 

Estoy burbujeando mi respuesta basada en expresiones regulares de una que publiqué anteriormente en los comentarios de otra respuesta. Creo que usar re es una solución más clara y explícita a este problema que str.rstrip .

 >>> import re 

Si desea eliminar uno o más caracteres de nueva línea finales :

 >>> re.sub(r'[\n\r]+$', '', '\nx\r\n') '\nx' 

Si desea eliminar caracteres de nueva línea en todas partes (no solo en el final):

 >>> re.sub(r'[\n\r]+', '', '\nx\r\n') 'x' 

Si desea eliminar solo 1-2 caracteres de nueva línea finales (es decir, \r , \n , \r\n , \n\r , \r\r , \n\n )

 >>> re.sub(r'[\n\r]{1,2}$', '', '\nx\r\n\r\n') '\nx\r' >>> re.sub(r'[\n\r]{1,2}$', '', '\nx\r\n\r') '\nx\r' >>> re.sub(r'[\n\r]{1,2}$', '', '\nx\r\n') '\nx' 

Tengo la sensación de que lo que la mayoría de la gente realmente quiere aquí es eliminar solo una aparición de un carácter de nueva línea final, ya sea \r\n o \n nada más.

 >>> re.sub(r'(?:\r\n|\n)$', '', '\nx\n\n', count=1) '\nx\n' >>> re.sub(r'(?:\r\n|\n)$', '', '\nx\r\n\r\n', count=1) '\nx\r\n' >>> re.sub(r'(?:\r\n|\n)$', '', '\nx\r\n', count=1) '\nx' >>> re.sub(r'(?:\r\n|\n)$', '', '\nx\n', count=1) '\nx' 

(El ?: Es para crear un grupo que no captura).

(Por cierto, esto no es lo que '...'.rstrip('\n', '').rstrip('\r', '') hace que no esté claro para otros que se topan con este hilo. str.rstrip mayor cantidad posible de caracteres finales, por lo que una cadena como foo\n\n\n resultaría en un falso positivo de foo mientras que es posible que desee conservar las otras nuevas líneas después de eliminar uno solo.)

Solo usa :

 line = line.rstrip("\n") 

o

 line = line.strip("\n") 

No necesitas nada de esto complicado

 >>> ' spacious '.rstrip() ' spacious' >>> "AABAA".rstrip("A") 'AAB' >>> "ABBA".rstrip("AB") # both AB and BA are stripped '' >>> "ABCABBA".rstrip("AB") 'ABC' 

Hay tres tipos de finales de línea que normalmente encontramos: \n , \r y \r\n . Una expresión regular bastante simple en re.sub , a saber r"\r?\n?$" , Es capaz de capturarlos a todos.

(Y tenemos que atraparlos a todos , ¿tengo razón?)

 import re re.sub(r"\r?\n?$", "", the_text, 1) 

Con el último argumento, limitamos el número de ocurrencias reemplazadas a una, imitando chomp hasta cierto punto. Ejemplo:

 import re text_1 = "hellothere\n\n\n" text_2 = "hellothere\n\n\r" text_3 = "hellothere\n\n\r\n" a = re.sub(r"\r?\n?$", "", text_1, 1) b = re.sub(r"\r?\n?$", "", text_2, 1) c = re.sub(r"\r?\n?$", "", text_3, 1) 

… donde a == b == c es True .

Si le preocupa la velocidad (digamos que tiene una larga lista de cadenas) y sabe la naturaleza de la nueva línea de caracteres, el corte de la cadena es más rápido que la rstrip. Una pequeña prueba para ilustrar esto:

 import time loops = 50000000 def method1(loops=loops): test_string = 'num\n' t0 = time.time() for num in xrange(loops): out_sting = test_string[:-1] t1 = time.time() print('Method 1: ' + str(t1 - t0)) def method2(loops=loops): test_string = 'num\n' t0 = time.time() for num in xrange(loops): out_sting = test_string.rstrip() t1 = time.time() print('Method 2: ' + str(t1 - t0)) method1() method2() 

Salida:

 Method 1: 3.92700004578 Method 2: 6.73000001907 

Esto funcionará tanto para Windows como para Linux (un poco caro con re sub si solo está buscando re)

 import re if re.search("(\\r|)\\n$", line): line = re.sub("(\\r|)\\n$", "", line) 

Una captura de todos:

 line = line.rstrip('\r|\n')