it-swarm.com.de

Wie kann ich eine nachgestellte Zeile in Python entfernen?

Was ist das Python-Äquivalent der chomp-Funktion von Perl, die das letzte Zeichen einer Zeichenfolge entfernt, wenn es sich um einen Zeilenvorschub handelt?

1430

Probieren Sie die Methode rstrip() aus (siehe doc Python 2 und Python 3 )

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

Die rstrip()-Methode von Python entfernt standardmäßig alle Arten von nachgestellten Leerzeichen, nicht nur eine neue Zeile, wie Perl dies mit chomp tut.

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

Um nur Zeilenumbrüche zu entfernen:

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

Es gibt auch die Methoden lstrip() und 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

Und ich würde sagen, die "Pythonic" -Methode, Zeilen ohne nachgestellte Zeilenumbrüche zu erhalten, ist splitlines ().

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

Die kanonische Methode zum Entfernen von Zeilenendezeichen (EOL-Zeichen) besteht darin, die Zeichenfolge rstrip () -Methode zu verwenden, um alle nachfolgenden\r oder\n zu entfernen. Hier finden Sie Beispiele für EOL-Zeichen für Mac, Windows und 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'

Die Verwendung von '\ r\n' als Parameter für rstrip bedeutet, dass alle nachfolgenden Kombinationen von '\ r' oder '\ n' entfernt werden. Deshalb funktioniert es in allen drei Fällen oben.

Diese Nuance ist in seltenen Fällen von Bedeutung. Ich musste zum Beispiel einmal eine Textdatei verarbeiten, die eine HL7-Nachricht enthielt. Der HL7-Standard erfordert ein abschließendes '\ r' als EOL-Zeichen. Der Windows-Computer, auf dem ich diese Nachricht verwendete, hatte sein eigenes EOL-Zeichen "\ r\n" angehängt. Daher sah das Ende jeder Zeile wie "\ r\r\n" aus. Die Verwendung von rstrip ('\ r\n') hätte das gesamte '\ r\r\n' weggenommen, was ich nicht wollte. In diesem Fall habe ich stattdessen einfach die letzten beiden Zeichen abgeschnitten.

Beachten Sie, dass im Gegensatz zur chomp-Funktion von Perl alle angegebenen Zeichen am Ende der Zeichenfolge entfernt werden, nicht nur eine:

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

Beachten Sie, dass sich rstrip nicht genau wie chomp () von Perl verhält, weil es den String nicht ändert. In Perl:

$x="a\n";

chomp $x

führt dazu, dass $x"a" ist.

aber in Python:

x="a\n"

x.rstrip()

bedeutet, dass der Wert von x noch "a\n" ist. Sogar x=x.rstrip() liefert nicht immer dasselbe Ergebnis, da der Whitespace vom Ende des Strings entfernt wird und nicht nur eine Newline.

98
Sameer Siruguri

Ich könnte so etwas verwenden:

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

Ich denke, das Problem mit rstrip("\n") ist, dass Sie wahrscheinlich sicherstellen möchten, dass das Trennzeichen tragbar ist. (Einige veraltete Systeme verwenden angeblich "\r\n"). Der andere Grund ist, dass rstrip sich wiederholt Whitespace entfernt. Hoffentlich enthält os.linesep die richtigen Zeichen. das oben genannte funktioniert für mich.

47
Jamie

Sie können line = line.rstrip('\n') verwenden. Dadurch werden alle Zeilenumbrüche vom Ende der Zeichenfolge entfernt, nicht nur eine.

39
octoback
s = s.rstrip()

entfernt alle Zeilenumbrüche am Ende der Zeichenfolge s. Die Zuweisung ist erforderlich, da rstrip eine neue Zeichenfolge zurückgibt, anstatt die ursprüngliche Zeichenfolge zu ändern. 

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

oder Sie könnten mit Regexs immer geekier werden :)

habe Spaß!

25
mihaicc

Dies würde genau das chomp von Perl (minus Verhalten auf Arrays) für den Zeilenabschluss "\ n" replizieren:

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

(Hinweis: Die Zeichenfolge "in place" wird nicht geändert; zusätzliche Leerzeichen werden nicht entfernt;\r\n wird berücksichtigt).

23
Alien Life Form

sie können Streifen verwenden:

line = line.strip()

demo:

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

Vorsicht bei "foo".rstrip(os.linesep): Dies wird nur die Zeilenumbrüche für die Plattform verschlüsseln, auf der Ihr Python ausgeführt wird. Stellen Sie sich vor, Sie schimpfen die Zeilen einer Windows-Datei beispielsweise unter Linux:

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

Verwenden Sie stattdessen "foo".rstrip("\r\n"), wie Mike oben sagt.

20
Carlos Valiente

Ein Beispiel in der Python-Dokumentation verwendet einfach line.strip().

Die chomp-Funktion von Perl entfernt eine Zeilenumbruchsequenz nur dann vom Ende einer Zeichenfolge, wenn sie tatsächlich vorhanden ist.

So plane ich das in Python, wenn process die Funktion ist, die ich brauche, um für jede Zeile dieser Datei etwas Nützliches zu tun:

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 macht nicht dasselbe wie chomp auf so vielen Ebenen. Lesen Sie http://perldoc.Perl.org/functions/chomp.html und sehen Sie, dass chomp in der Tat sehr komplex ist.

Mein Hauptpunkt ist jedoch, dass chomp höchstens ein Zeilenende entfernt, wohingegen rstrip so viele wie möglich entfernen wird.

Hier können Sie sehen, wie rstrip alle Zeilenumbrüche entfernt:

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

Eine weitaus genauere Annäherung an die typische Perl-Chomp-Verwendung kann mit resub wie folgt erreicht werden:

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

Ich programmiere nicht in Python, aber ich bin auf python.org auf FAQ gestoßen, um S.rstrip ("\ r\n") für Python 2.2 oder höher zu unterstützen.

14
Andrew Grimm
import re

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

Wenn Sie alle Zeilenumbrüche in einem mehrzeiligen str-Objekt (oldstr) bereinigen möchten, können Sie es nach dem Trennzeichen '\ n' in eine Liste aufteilen und diese Liste dann zu einem neuen str (newstr) zusammenfügen.

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

8
Leozj

problemumgehungslösung für spezielle Fälle:

wenn das Zeilenvorschubzeichen das letzte Zeichen ist (wie bei den meisten Dateieingaben), können Sie für jedes Element in der Auflistung wie folgt indizieren: 

foobar= foobar[:-1]

um Ihren Newline-Charakter herauszuschneiden. 

8
Chij

Es scheint, als gäbe es kein perfektes Analogon für chomp von Perl. Insbesondere kann rstrip keine Trennzeichen für mehrzeilige Zeilenumbrüche wie \r\n verwenden. Splitlines tut wie hier ausgeführt . Nach meiner Antwort auf einer anderen Frage können Sie join und splitlines zum Entfernen/Ersetzen aller Newlines aus einem String s:

''.join(s.splitlines())

Folgendes entfernt genau eine nachlaufende Zeile Newline (wie Chomp würde, glaube ich). Wenn Sie True als keepends-Argument an Splitlines übergeben, bleiben die Trennzeichen erhalten. Dann wird splitlines erneut aufgerufen, um die Trennzeichen nur für die letzte "Zeile" zu entfernen: 

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

Ich finde es praktisch, die gechompten Zeilen über einen Iterator abrufen zu können, parallel zu der Art, wie Sie die nicht gechompten Zeilen von einem Dateiobjekt erhalten können. Sie können dies mit dem folgenden Code tun:

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

Verwendungsbeispiel:

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

Ich sprudle meine Antwort, die auf einem regulären Ausdruck basiert, von einer Antwort, die ich zuvor in den Kommentaren einer anderen Antwort gepostet hatte. Ich denke, die Verwendung von re ist eine eindeutigere Lösung für dieses Problem als str.rstrip.

>>> import re

Wenn Sie eine oder mehrere nachfolgende Zeilenumbrüche entfernen möchten:

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

Wenn Sie Zeilenumbrüche überall entfernen möchten (nicht nur nachlaufend):

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

Wenn Sie nur 1-2 nachfolgende Zeilenvorschubzeichen entfernen möchten (d. H. \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'

Ich habe das Gefühl, was die meisten Leute hier wirklich wollen, ist das Entfernen von one eines nachgestellten Zeilenumbruchs, entweder \r\n oder \n, und nichts mehr.

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

(Der ?: dient zum Erstellen einer nicht erfassenden Gruppe.)

(Übrigens ist dies nicht, was '...'.rstrip('\n', '').rstrip('\r', '') macht, was anderen möglicherweise nicht klar ist, wenn sie über diesen Thread stolpern. str.rstrip entfernt so viele der nachfolgenden Zeichen wie möglich, sodass eine Zeichenfolge wie foo\n\n\n zu einem falschen positiven Wert von foo führen würde. Möglicherweise wollten Sie die anderen Zeilenumbrüche beibehalten, nachdem Sie eine einzelne nachgestellte entfernt haben.)

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

Benutz einfach : 

line = line.rstrip("\n")

oder

line = line.strip("\n")

Du brauchst nichts von diesem komplizierten Zeug

4
Help me

Es gibt drei Arten von Zeilenenden, auf die wir normalerweise stoßen: \n, \r und \r\n. Ein recht einfacher regulärer Ausdruck in re.sub , nämlich r"\r?\n?$", kann sie alle fangen.

(Und wir muss sie alle fangen, habe ich recht?)

import re

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

Mit dem letzten Argument beschränken wir die Anzahl der Vorkommen, die ersetzt werden, auf eins, was chomp ein wenig nachahmt. Beispiel:

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)

... wobei a == b == cTrue ist.

3
internetional

Wenn Sie sich Gedanken über die Geschwindigkeit machen (sagen Sie, Sie haben eine lange Liste von Strings) und Sie wissen, was das Zeichen für das Newline-Zeichen ist, ist das Schneiden von Strings tatsächlich schneller als bei rstrip. Ein kleiner Test, um dies zu veranschaulichen:

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

Ausgabe:

Method 1: 3.92700004578
Method 2: 6.73000001907
1
Stephen Miller

Dies funktioniert sowohl für Windows als auch für Linux (etwas teurer mit re sub, wenn Sie nur nach einer Lösung suchen)

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

0
Venfah Nazir