Wie entferne ich das letzte Zeichen einer Zeichenkette, wenn es ein Zeilenumbruch ist?
"abc\n" --> "abc"
Wie entferne ich das letzte Zeichen einer Zeichenkette, wenn es ein Zeilenumbruch ist?
"abc\n" --> "abc"
Ich finde es praktisch, wenn man die zerhackten Zeilen über einen Iterator abrufen kann, so wie man auch die nicht zerhackten Zeilen aus einem Dateiobjekt abrufen kann. Sie können dies mit dem folgenden Code tun:
def chomped_lines(it):
return map(operator.methodcaller('rstrip', '\r\n'), it)
Beispielhafte Verwendung:
with open("file.txt") as infile:
for line in chomped_lines(infile):
process(line)
Anmerkung: Mit operator.methodcaller
y map
( itertools.imap
auf Py2) können Sie diese Arbeit in die C-Schicht verlagern und so den Generatorcode auf Python-Ebene vermeiden (und dadurch ein wenig schneller laufen, obwohl der E/A-Overhead zugegebenermaßen wahrscheinlich kleine Gewinne überdeckt): for line in map(operator.methodcaller('rstrip', '\r\n'), infile):
. Es könnte noch herausgerechnet werden als def chomped_lines(it): return map(operator.methodcaller('rstrip', '\r\n'), it)
.
Ich baue meine auf regulären Ausdrücken basierende Antwort aus einer Antwort auf, die ich zuvor in den Kommentaren einer anderen Antwort gepostet habe. Ich denke, mit re
ist eine klarere und deutlichere Lösung für dieses Problem als str.rstrip
.
>>> import re
Wenn Sie einen oder mehrere der folgenden Punkte entfernen möchten hintere Zeilenumbruch-Zeichen:
>>> re.sub(r'[\n\r]+$', '', '\nx\r\n')
'\nx'
Wenn Sie Zeilenumbrüche überall entfernen wollen (nicht nur am Ende):
>>> re.sub(r'[\n\r]+', '', '\nx\r\n')
'x'
Wenn Sie nur 1-2 hintere Zeilenumbrüche 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, dass nur die eine Auftreten eines nachgestellten Zeilenumbruchs, entweder \r\n
o \n
und nichts weiter.
>>> 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'
(Die ?:
ist es, eine nicht fangende Gruppe zu bilden).
(Übrigens ist dies pas was '...'.rstrip('\n', '').rstrip('\r', '')
tut, was anderen, die über diesen Thread stolpern, vielleicht nicht klar ist. str.rstrip
entfernt so viele der nachstehenden Zeichen wie möglich, so dass eine Zeichenkette wie foo\n\n\n
würde zu einem falsch positiven Ergebnis von foo
wohingegen Sie vielleicht die anderen Zeilenumbrüche nach dem Entfernen eines einzelnen nachgestellten Zeilenumbruchs beibehalten wollten).
Mit der Regex können Sie die nicht erfassende Gruppe auslassen, auch für Ihren letzten Ansatz. r'\r?\n$'
. Wahrscheinlich effizienter, da Regex-Engines eine härtere Zeit haben, Alternationen zu optimieren. Beachten Sie auch, dass es deutlich schneller ist, wenn Sie dies viele Male tun (besonders wenn Sie sich mit anderen Regexen vermischen). re
verwendet) zu re.compile
den Ausdruck einmal im Voraus, dann verwenden Sie die sub
Methode des kompilierten Regex-Objekts; Modulfunktionen sind auf Python-Ebene angesiedelt und überprüfen zunächst einen Cache auf kompilierte Regexe (und erstellen/zwischenspeichern sie, falls sie fehlen) und rufen dann die passende Methode auf; das Überspringen dieser Suche hilft.
Es sieht so aus, als gäbe es kein perfektes Analogon für Perl's mampfen . Insbesondere, rstrip kann nicht mit mehrstelligen Zeilenumbrüchen wie \r\n
. Allerdings, Splitlines する wie hier hervorgehoben . Unter meine Antwort zu einer anderen Frage, können Sie kombinieren beitreten et Splitlines zum Entfernen/Ersetzen aller Zeilenumbrüche aus einer Zeichenkette s
:
''.join(s.splitlines())
Das Folgende wird entfernt genau eine hintere newline (wie chomp, glaube ich). Übergabe True
als die keepends
Argument an splitlines die Begrenzungszeichen beibehalten. Dann wird splitlines erneut aufgerufen, um die Begrenzungszeichen nur in der letzten "Zeile" zu entfernen:
def chomp(s):
if len(s):
lines = s.splitlines(True)
last = lines.pop()
return ''.join(lines + last.splitlines())
else:
return ''
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
4 Stimmen
Superset: beliebige Zeichenkette anstelle von nur newline: stackoverflow.com/questions/1038824/
9 Stimmen
Die A+-Antwort lautet, wenn dies darauf zurückzuführen ist, dass vergessen wurde
open()
eine Datei mit dem entsprechenden 'newline=...' Parameter für Ihre Plattform (universelle Unterstützung von Zeilenumbrüchen), müssen Sie ihn möglicherweise nicht explizit entfernen.