web-dev-qa-db-fra.com

Comment puis-je supprimer une nouvelle ligne de fin en Python?

Quel est l'équivalent Python de la fonction chomp de Perl, qui supprime le dernier caractère d'une chaîne s'il s'agit d'une nouvelle ligne?

1430

Essayez la méthode rstrip() (voir doc Python 2 et Python 3 )

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

La méthode rstrip() de Python supprime tous les types d'espaces de fin, par défaut, et non une nouvelle ligne comme le fait Perl avec chomp .

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

Pour ne supprimer que les nouvelles lignes:

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

Il existe aussi les méthodes lstrip() et 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'
1524
Rich Bradshaw

Et je dirais que la méthode "pythonique" pour obtenir des lignes sans les caractères de fin de ligne est le splitlines ().

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

La méthode la plus efficace pour supprimer les caractères de fin de ligne consiste à utiliser la méthode string rstrip () en supprimant tout\r ou\n final. Voici des exemples de caractères EOL pour Mac, Windows et 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'

Utiliser '\ r\n' comme paramètre à rstrip signifie que cela supprimera toute combinaison finale de '\ r' ou '\ n'. C'est pourquoi cela fonctionne dans les trois cas ci-dessus.

Cette nuance compte dans de rares cas. Par exemple, une fois, j'ai dû traiter un fichier texte contenant un message HL7. La norme HL7 requiert un "\ r" final comme caractère EOL. La machine Windows sur laquelle j’utilisais ce message avait ajouté son propre caractère '\ r\n' EOL. Par conséquent, la fin de chaque ligne ressemblait à "\ r\r\n". Utiliser rstrip ('\ r\n') aurait enlevé tout le '\ r\r\n' qui n’est pas ce que je voulais. Dans ce cas, j'ai simplement coupé les deux derniers caractères à la place.

Notez que contrairement à la fonction chomp de Perl, tous les caractères spécifiés à la fin de la chaîne seront supprimés, pas un seul:

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

Notez que rstrip n'agit pas exactement comme la méthode chomp () de Perl car il ne modifie pas la chaîne. C'est-à-dire en Perl:

$x="a\n";

chomp $x

résulte en $x étant "a".

mais en Python:

x="a\n"

x.rstrip()

signifiera que la valeur de x est still "a\n". Même x=x.rstrip() ne donne pas toujours le même résultat, car il supprime tous les espaces blancs de la fin de la chaîne, pas seulement une nouvelle ligne.

98
Sameer Siruguri

Je pourrais utiliser quelque chose comme ça:

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

Je pense que le problème avec rstrip("\n") est que vous voudrez probablement vous assurer que le séparateur de lignes est portable. (certains systèmes obsolètes sont supposés utiliser "\r\n"). L’autre acquis est que rstrip supprimera les espaces répétés. Espérons que os.linesep contiendra les bons caractères. ce qui précède fonctionne pour moi.

47
Jamie

Vous pouvez utiliser line = line.rstrip('\n'). Cela supprimera toutes les nouvelles lignes de la fin de la chaîne, pas une seule.

39
octoback
s = s.rstrip()

enlèvera toutes les nouvelles lignes à la fin de la chaîne s. L'affectation est nécessaire car rstrip renvoie une nouvelle chaîne au lieu de modifier la chaîne d'origine. 

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

ou vous pouvez toujours devenir geekier avec les expressions rationnelles :)

s'amuser!

25
mihaicc

Cela répliquerait exactement le chomp de Perl (comportement moins sur les tableaux) pour le terminateur de ligne "\ 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

(Remarque: il ne modifie pas la chaîne 'in place'; il ne supprime pas les espaces finaux supplémentaires; prend en compte\r\n)

23
Alien Life Form

vous pouvez utiliser strip:

line = line.strip()

démo:

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

Attention avec "foo".rstrip(os.linesep): Cela ne modifiera que les caractères de nouvelle ligne de la plate-forme sur laquelle votre Python est exécuté. Imaginez que vous modifiez les lignes d’un fichier Windows sous Linux, par exemple:

$ 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'
>>>

Utilisez plutôt "foo".rstrip("\r\n"), comme le dit Mike ci-dessus.

20
Carlos Valiente

Un exemple dans la documentation de Python utilise simplement line.strip().

La fonction chomp de Perl supprime une séquence de saut de ligne de la fin d'une chaîne uniquement si elle est réellement présente.

Voici comment je compte le faire en Python, si process est conceptuellement la fonction dont j'ai besoin pour faire quelque chose d’utile pour chaque ligne de ce fichier:

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)
19
minopret

rstrip ne fait pas la même chose que chomp, à tant de niveaux. Lire http://perldoc.Perl.org/functions/chomp.html et voir que chomp est vraiment très complexe.

Cependant, mon point principal est que chomp supprime au plus une fin de ligne, alors que rstrip en supprimera autant que possible.

Ici vous pouvez voir que rstrip supprime toutes les nouvelles lignes:

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

Avec re.sub, vous pouvez obtenir une approximation beaucoup plus précise de l’utilisation type de Perl Chomp:

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

Je ne programme pas en Python, mais je suis tombé sur un FAQ at python.org préconisant S.rstrip ("\ r\n") pour Python 2.2 ou version ultérieure.

14
Andrew Grimm
import re

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

Si votre question est de nettoyer tous les sauts de ligne dans un objet str de plusieurs lignes (oldstr), vous pouvez le scinder en une liste en fonction du délimiteur '\ n', puis rejoindre cette liste dans une nouvelle str (newstr).

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

8
Leozj

solution de contournement pour cas particulier:

si le caractère de nouvelle ligne est le dernier caractère (comme c'est le cas avec la plupart des entrées de fichier), vous pouvez alors indexer tout élément de la collection comme suit: 

foobar= foobar[:-1]

pour trancher votre personnage newline. 

8
Chij

Il semble qu'il n'y ait pas d'analogue parfait pour le chomp de Perl. En particulier, (rstrip) ne peut pas gérer les délimiteurs de nouvelle ligne à plusieurs caractères tels que \r\n. Cependant, lignes fractionnées fait comme indiqué ici . Après ma réponse sur une question différente, vous pouvez combiner joindre et splitlines pour supprimer/remplacer toutes les nouvelles lignes d'une chaîne s:

''.join(s.splitlines())

Ce qui suit supprime exactement une nouvelle ligne trailing (comme le ferait chomp, je crois). Si vous passez True en tant qu'argument keepends pour scinder les lignes, les délimiteurs sont conservés. Ensuite, splitlines est appelée à nouveau pour supprimer les délimiteurs uniquement sur la dernière "ligne": 

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

Je trouve pratique de pouvoir obtenir les lignes chompées via l'itérateur, parallèlement à la manière dont vous pouvez obtenir les lignes non chompées d'un objet File Vous pouvez le faire avec le code suivant:

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

Exemple d'utilisation:

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

Je bouillonne ma réponse basée sur l'expression régulière d'une réponse que j'ai postée plus tôt dans les commentaires d'une autre réponse. Je pense que l'utilisation de re est une solution plus claire et plus explicite à ce problème que str.rstrip.

>>> import re

Si vous souhaitez supprimer un ou plusieurs caractères trailing newline:

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

Si vous souhaitez supprimer les caractères de nouvelle ligne partout (pas seulement à la fin):

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

Si vous souhaitez supprimer uniquement les 1 ou 2 caractères de fin de ligne (c.-à-d., \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'

J'ai le sentiment que ce que la plupart des gens veulent vraiment ici, est de ne supprimer que un l'occurrence d'un caractère de fin de ligne, soit \r\n ou \n et rien de plus.

>>> 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'

(Le ?: permet de créer un groupe sans capture.)

(Au fait, c'est pas ce que '...'.rstrip('\n', '').rstrip('\r', '') fait, ce qui peut ne pas être clair pour les autres qui tombent sur ce fil. str.rstrip supprime autant de caractères de fin que possible, donc une chaîne comme foo\n\n\n donnerait un faux positif de foo alors que vous avez peut-être voulu conserver les autres nouvelles lignes après en avoir effacé une seule.

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

Il suffit d'utiliser: 

line = line.rstrip("\n")

ou

line = line.strip("\n")

Vous n'avez besoin d'aucun de ces trucs compliqués

4
Help me

Nous rencontrons normalement trois types de fins de ligne: \n, \r et \r\n. Une expression régulière assez simple dans re.sub , à savoir r"\r?\n?$", est capable de toutes les attraper.

(Et nous je dois les attraper tous, ai-je raison?)

import re

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

Avec le dernier argument, nous limitons le nombre d'occurrences remplacées à un, imitant dans une certaine mesure chomp. Exemple:

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)

... où a == b == c est True.

3
internetional

Si vous êtes préoccupé par la vitesse (disons que vous avez une longue liste de chaînes) et que vous connaissez la nature du caractère de nouvelle ligne, le découpage de chaîne est en réalité plus rapide que rstrip. Un petit test pour illustrer ceci:

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()

Sortie:

Method 1: 3.92700004578
Method 2: 6.73000001907
1
Stephen Miller

Cela fonctionnera à la fois pour Windows et Linux (un peu cher avec re sous si vous cherchez seulement une solution)

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

0
Venfah Nazir