Wie kann ich einen nachgestellten Zeilenumbruch entfernen?
1689
Was ist das Python-Äquivalent zu Perls chompFunktion, bei der das letzte Zeichen einer Zeichenfolge entfernt wird, wenn es sich um eine neue Zeile handelt?
Die Antwort A + lautet: Wenn dies darauf zurückzuführen ist, dass open()eine Datei mit dem entsprechenden Parameter 'newline = ...' für Ihre Plattform vergessen wurde (universelle Newline-Unterstützung), müssen Sie diese möglicherweise nicht explizit entfernen.
smci
Antworten:
1868
Probieren Sie die Methode aus rstrip()(siehe Dokument Python 2 und Python 3 ).
>>>'test string\n'.rstrip()'test string'
Die Python- rstrip()Methode entfernt standardmäßig alle Arten von nachgestellten Leerzeichen, nicht nur eine neue Zeile, wie dies bei Perl der Fall ist chomp.
Ich bin keine Python-Person, daher habe ich keine Antwort darauf, aber Perls chomp () entfernt tatsächlich das Trennzeichen für Eingabedatensätze vom Ende. Das ist eine neue Zeile zu Unixy-Dingen, kann aber anders sein (z. B. Windows) und ist veränderlich. Gibt es eine Möglichkeit, diesen Wert nur einmal vom Ende einer Zeichenfolge zu entfernen?
Brian D Foy
5
brian d foy: Python hat kein Trennzeichen für Eingabedatensätze wie awk und Perl.
Peter Hosey
7
@csde_rats, das stimmt nicht: OS X verwendet \nfür Zeilenumbrüche genau wie Unix. (Vor OS X wurde MacOS \rals Zeilentrennzeichen verwendet, aber das endete vor 10 Jahren.)
Skue
21
@briandfoy Python bietet integrierte Unterstützung für Universal Newlines (nur beim Lesen, nicht beim Schreiben). Sie öffnen die Datei entweder im "U" - oder im "rU" -Modus und dann, unabhängig von Windows, Linux, Mac, was auch immer, bis der Text Ihren Python-Code erreicht, wurde jeder Zeilenumbruchstil durch "\ n" ersetzt. Siehe: python.org/dev/peps/pep-0278
AlcubierreDrive
12
Ich werde weitermachen und dies darlegen, weil ich ein Noob bin und mich eine Weile gefragt habe, warum es nicht funktioniert hat. .strip()ändert den String nicht (hat wahrscheinlich etwas mit unveränderlichen Strings zu tun). Wenn nicht in der Kommandozeile, wollen Sie"string = string.strip()"
Script Kitty
158
Und ich würde sagen, der "pythonische" Weg, um Zeilen ohne nachgestellte Zeilenumbrüche zu erhalten, ist splitlines ().
Die kanonische Methode zum Entfernen von Zeilenendezeichen (EOL) besteht darin, die Methode string rstrip () zu verwenden, um nachfolgende \ r oder \ n zu entfernen. Hier finden Sie Beispiele für Mac-, Windows- und Unix-EOL-Zeichen.
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 oben genannten Fällen.
Diese Nuance ist in seltenen Fällen von Bedeutung. Zum Beispiel musste ich 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 verwendet habe, hat ein 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' entfernt, was nicht das ist, was ich wollte. In diesem Fall habe ich stattdessen einfach die letzten beiden Zeichen abgeschnitten.
Beachten Sie, dass im Gegensatz zu Perls chompFunktion alle angegebenen Zeichen am Ende der Zeichenfolge entfernt werden, nicht nur eines:
Beachten Sie, dass moderne Mac OS X-Apps \ n verwenden. Nur alte Carbon-Apps, die ursprünglich für Mac OS geschrieben wurden, verwenden \ r.
Peter Hosey
2
Danke für die Klarstellung. Natürlich funktioniert der rstrip ('\ r \ n') auch in diesem Fall noch.
Mike
13
Es gibt auch os.linesepdie EOL-Sequenz für das aktuelle Betriebssystem.
Eli Collins
Dies ist die beste Antwort: Es werden nur Zeilenumbrüche entfernt und für die gängigsten Plattformen korrekt ausgeführt.
Kevinarpe
plus +1 Für die Verwendung von \nund\r
fechnert
99
Beachten Sie, dass rstrip nicht genau wie Perls chomp () funktioniert, da es den String nicht ändert. Das heißt, in Perl:
$x="a\n";
chomp $x
führt zu $xSein "a".
aber in Python:
x="a\n"
x.rstrip()
wird bedeuten, dass der Wert von ximmer noch ist"a\n" . Auch x=x.rstrip()gibt nicht immer das gleiche Ergebnis, da alle Leerzeichen vom Ende der Zeichenfolge entfernt werden, nicht nur höchstens eine neue Zeile.
Außerdem entfernt strip () wiederholte Zeichen, während chop / chomp nur eine neue
Zeile
50
Ich könnte so etwas verwenden:
import os
s = s.rstrip(os.linesep)
Ich denke, das Problem dabei rstrip("\n")ist, dass Sie wahrscheinlich sicherstellen möchten, dass das Zeilentrennzeichen tragbar ist. (Einige veraltete Systeme sollen verwendet werden "\r\n"). Das andere Problem ist, dass rstripwiederholte Leerzeichen entfernt werden. Hoffentlich os.linesepenthält die richtigen Zeichen. Das obige funktioniert für mich.
Dies funktioniert jedoch nicht, wenn Sie versuchen, vom Benutzer übermittelte Inhalte in einer Webanwendung zu bereinigen. Der Benutzerinhalt kann aus einer beliebigen Quelle stammen und neue Zeilenumbrüche enthalten.
Apiguy
2
Guter Punkt, außer dass Sie möglicherweise "fremde" Dateien (von veralteten Systemen) auf Ihrem modernen Betriebssystem verarbeiten.
ChuckCottrill
1
Beachten Sie auch, dass dies beim Lesen einer Datei im Textmodus auch auf einem Windows-System nicht funktioniert, da das nachfolgende Zeichen immer in '\ n' konvertiert wird.
Mad Physicist
@MadPhysicist Sie haben Recht, dass es es konvertiert, aber es funktioniert immer noch, weil es mit den Zeichen im Argument identisch ist rstrip('\r\n')und rstrip()diese entfernt.
dtauxe
41
Sie können verwenden line = line.rstrip('\n'). Dadurch werden alle Zeilenumbrüche vom Ende der Zeichenfolge entfernt, nicht nur eine.
entfernt alle Zeilenumbrüche am Ende der Zeichenfolge s. Die Zuweisung wird benötigt, da rstripeine neue Zeichenfolge zurückgegeben wird, anstatt die ursprüngliche Zeichenfolge zu ändern.
Dies würde genau Perls Chomp (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 'an Ort und Stelle' wird nicht geändert. Es werden keine zusätzlichen nachgestellten Leerzeichen entfernt. Berücksichtigt \ r \ n.)
Dies funktionierte hervorragend für mich, als ich versuchte, eine Textdatei mit Zeilenenden schnell in eine Textzeile umzuwandeln. Ich bin ein Neuling, also nicht sicher, ob es einen besseren Weg gibt, aber es hat funktioniert, danke! (Strip schien nur von den Enden zu funktionieren, nicht intern)
Steve Koch
2
Warum nicht einfach eine Ersetzungsanweisung verwenden, wie .replace('\n|\r', '')?
Türknauf
2
Nur für den Fall, dass jemand anderes die Idee von @DoorknobofSnow verwenden möchte, ist es nur eine kleine Änderung, das Regex-Modul zu verwenden: import rere.sub('\n|\r', '', '\nx\n\r\n')==> 'x'.
Taylor Edmiston
Die Verwendung dieser und der Regex-Technik, wie @TaylorEdmiston erwähnt, sollte die richtige Antwort sein.
Bhargav
@Bhargav Ich habe eine Antwort auf diese Frage basierend auf diesem Kommentar hinzugefügt, wie Sie vorgeschlagen haben, und gleichzeitig einige andere verwandte Optionen untersucht. Ich habe auch klargestellt, warum ich denke, dass Regex eine bessere Lösung für dieses Problem ist als str.rstrip, da dies die meisten Antworten verwenden.
Kudos, Sie sind der einzige, der auf dieses sehr wichtige Detail hingewiesen hat. Wie bereits erwähnt, funktioniert die Verwendung von os.linesep jedoch nicht, wenn Sie Dateien von einem anderen System lesen. Dies kann in Python etwas mehr Arbeit erfordern und das Ende der Zeile überprüfen.
Brianmearns
19
Vorsicht bei "foo".rstrip(os.linesep): Dadurch werden nur die Zeilenumbruchzeichen für die Plattform verarbeitet, auf der Ihr Python ausgeführt wird. Stellen Sie sich vor, Sie schimpfen unter Linux mit den Zeilen einer Windows-Datei, zum Beispiel:
$ python
Python2.7.1(r271:86832,Mar182011,09:09:48)[GCC 4.5.020100604[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 "foo".rstrip("\r\n")stattdessen, wie Mike oben sagt.
Perls chompFunktion entfernt eine Zeilenumbruchsequenz nur dann vom Ende einer Zeichenfolge, wenn sie tatsächlich vorhanden ist.
So plane ich das in Python, wenn dies processkonzeptionell die Funktion ist, die ich benötige, um für jede Zeile aus 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)
Dadurch werden auch Tabulator-Leerzeichen entfernt, die in der ursprünglichen Frage nicht angefordert werden. (Aufgrund des \ t-Charakters)
NoahR
9
Ich finde es praktisch, die gechompten Zeilen im Iterator abrufen zu können, parallel zu der Art und Weise, wie Sie die nicht gechompten Zeilen von einem Dateiobjekt abrufen können. Sie können dies mit dem folgenden Code tun:
Hinweis: Mit operator.methodcallerund map( itertools.imapauf Py2) können Sie diese Arbeit auf die C-Ebene übertragen, indem Sie den Code des Python-Level-Generators vermeiden (und dadurch etwas schneller laufen, obwohl der E / A-Overhead zugegebenermaßen kleine Gewinne maskieren kann) : for line in map(operator.methodcaller('rstrip', '\r\n'), infile):. Es könnte immer noch als herausgerechnet werden def chomped_lines(it): return map(operator.methodcaller('rstrip', '\r\n'), it).
ShadowRanger
8
Problemumgehungslösung für Sonderfälle:
Wenn das Zeilenumbruchzeichen das letzte Zeichen ist (wie dies bei den meisten Dateieingaben der Fall ist), können Sie für jedes Element in der Sammlung Folgendes indizieren:
Manchmal ist das Newline nicht ein letztes Zeichen, aber die letzten, speziell auf Fenster, wie andere haben darauf hingewiesen.
Cacovsky
8
Wenn Sie alle Zeilenumbrüche in einem mehrzeiligen str-Objekt (oldstr) bereinigen möchten, können Sie es gemäß dem Trennzeichen '\ n' in eine Liste aufteilen und diese Liste dann zu einem neuen str (newstr) zusammenfügen.
Es sieht so aus, als gäbe es kein perfektes Analogon für Perls Chomp . Insbesondere kann rstrip keine Newline-Trennzeichen mit mehreren Zeichen wie verarbeiten \r\n. Allerdings Teilungslinien nicht wie hier darauf hingewiesen . Nach meiner Antwort auf eine andere Frage, können Sie kombinieren beitreten und Teilungslinien entfernen / ersetzen Sie alle Zeilenumbrüche aus einem String s:
''.join(s.splitlines())
Folgende entfernt genau ein nachlauf Newline (wie chomp würde, glaube ich). Bei Trueder keependsÜbergabe als Argument an Splitlines bleiben die Trennzeichen erhalten. Dann wird Splitlines erneut aufgerufen, um die Trennzeichen nur in der letzten "Zeile" zu entfernen:
Ich sprudle meine auf regulären Ausdrücken basierende Antwort von einer, die ich zuvor in den Kommentaren einer anderen Antwort gepostet habe. Ich denke, die Verwendung reist eine klarere und explizitere Lösung für dieses Problem als str.rstrip.
>>>import re
Wenn Sie ein oder mehrere nachgestellte Zeilenumbrüche entfernen möchten:
>>> re.sub(r'[\n\r]+$','','\nx\r\n')'\nx'
Wenn Sie Zeilenumbrüche überall entfernen möchten (nicht nur am Ende):
>>> re.sub(r'[\n\r]+','','\nx\r\n')'x'
Wenn Sie nur 1-2 Newline Zeichen (dh entfernen \r, \n, \r\n, \n\r, \r\r, \n\n)
Ich habe das Gefühl, was die meisten Leute hier wirklich wollen, ist, nur ein Vorkommen eines nachgestellten Zeilenumbruchs zu entfernen , entweder \r\noder \nund nichts weiter.
(Das ?:ist, um eine nicht erfassende Gruppe zu erstellen.)
(Übrigens ist dies nicht das, was '...'.rstrip('\n', '').rstrip('\r', '')für andere, die über diesen Thread stolpern, möglicherweise nicht klar ist. str.rstripEntfernt so viele der nachfolgenden Zeichen wie möglich, sodass eine Zeichenfolge wie foo\n\n\nein falsches Positiv von ergibt, foowährend Sie möglicherweise die beibehalten möchten andere Zeilenumbrüche nach dem Entfernen eines einzelnen nachfolgenden.)
Sie können die nicht erfassende Gruppe auch für Ihren endgültigen Ansatz mit dem regulären Ausdruck überspringen r'\r?\n$'. Wahrscheinlich effizienter, da es für Regex-Motoren schwieriger ist, Wechsel zu optimieren. Beachten Sie auch, dass der Ausdruck , wenn Sie dies mehrmals tun re, re.compileim Vorfeld erheblich schneller ist (insbesondere, wenn Sie sich mit anderen Verwendungszwecken vermischen). Verwenden Sie dann die subMethode des kompilierten regulären Ausdrucksobjekts . Modulfunktionen sind auf Python-Ebene und überprüfen zuerst einen Cache auf kompilierte reguläre Ausdrücke (Erstellen / Zwischenspeichern, falls nicht vorhanden) und rufen dann die Matching-Methode auf. Das Überspringen dieser Suche hilft.
ShadowRanger
1
Randnotiz: Da Sie versuchen, das \ndirekt abzugleichen , möchten Sie möglicherweise \Zover verwenden $(oder einfach nur übereinstimmen \r?$, da $implizit kurz vor der neuen Zeile am Ende eines Strings übereinstimmen kann).
ShadowRanger
5
>>>' spacious '.rstrip()' spacious'>>>"AABAA".rstrip("A")'AAB'>>>"ABBA".rstrip("AB")# both AB and BA are stripped''>>>"ABCABBA".rstrip("AB")'ABC'
Das Beispiel, das ich brauchte! Rstrip ("\ r \ n") entfernt also sowohl '\ n' als auch '\ r' in beliebiger Kombination am Ende der Zeile!
Agostino
@ Agostino Keine Notwendigkeit zu liefern "\r\n"Zum Beispiel: ' spacious \n\r\n\r \n\n'.rstrip()produziert' spacious'
olibre
2
@olibre Der von Ihnen vorgeschlagene Code entfernt auch andere Leerzeichen, die möglicherweise nicht den Anforderungen entsprechen. Tatsächlich musste ich nur Kombinationen von Eol-Zeichen entfernen. Trotzdem danke, dass Sie darauf hingewiesen haben.
Beachten Sie, dass dies nicht mit chomp identisch ist.
Flimm
4
s ='''Hello World \t\n\r\tHi There'''# import the module string import string
# use the method translate to convert
s.translate({ord(c):Nonefor c in string.whitespace}>>'HelloWorldHiThere'
Mit Regex
s =''' Hello World
\t\n\r\tHi '''print(re.sub(r"\s+","", s), sep='')# \s matches all white spaces>HelloWorldHi
Ersetzen Sie \ n, \ t, \ r
s.replace('\n','').replace('\t','').replace('\r','')>' Hello World Hi '
Mit Regex
s ='''Hello World \t\n\r\tHi There'''
regex = re.compile(r'[\n\r\t]')
regex.sub("", s)>'Hello World Hi There'
mit Join
s ='''Hello World \t\n\r\tHi There'''' '.join(s.split())>'Hello World Hi There'
Es gibt drei Arten von Zeilenenden , dass wir normalerweise auftreten: \n, \rund \r\n. Ein ziemlich einfacher regulärer Ausdruck in re.subnämlich r"\r?\n?$"kann sie alle fangen.
(Und wir müssen sie alle fangen , habe ich recht?)
import re
re.sub(r"\r?\n?$","", the_text,1)
Mit dem letzten Argument begrenzen wir die Anzahl der ersetzten Vorkommen auf eins und ahmen Chomp bis zu einem gewissen Grad nach. 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)
Sie brauchen nicht einmal vollwertige reguläre Ausdrücke. rstrip("\r\n")ist ein Allheilmittel. Versuchen Sie es print(text_2.rstrip('\r\n')).
Agostino
@ Agostino: Stimmt, da dies str.rstrip()das Problem löst. Es hängt davon ab, welche Bedürfnisse Sie haben. Diese Lösung wird für die Fälle speziell gemacht , wenn Sie nur die letzte entfernen müssen "\n", "\r"oder "\r\n"aber nicht alle von ihnen (wenn es mehrere sind "\n"in der Zeichenfolge). re.sub(r"\r?\n?$", "", text_1, 1)gibt zurück "hellothere\n\n"und gibt text_1.rstrip("\r\n")zurück, "hellothere"was eine andere Zeichenfolge ist.
Internetional
Was ich damit sagen will, ist: Das str.strip()ist ein Allheilmittel, manchmal ist es genau das Problem.
Internetional
1
Wenn Sie sich Gedanken über die Geschwindigkeit machen (sagen wir, Sie haben eine lange Liste von Zeichenfolgen) und die Art des Newline-Zeichens kennen, ist das Schneiden von Zeichenfolgen tatsächlich schneller als rstrip. Ein kleiner Test, um dies zu veranschaulichen:
import time
loops =50000000def 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()
Ich weiß, dass ich wahrscheinlich "globale Schleifen" innerhalb der Funktionen verwenden sollte, aber das funktioniert auch.
Stephen Miller
Dieser Test ist falsch und nicht fair. method1Sie hacken nur das letzte Zeichen ab, egal was passiert, bei method2den .rstrip()ersten Überprüfungen, ob das Ende des Strings unerwünschte Zeichen enthält und sie abhackt, nur wenn einige gefunden wurden. Bitte überprüfen Sie die Zeichen method1und testen Sie sie erneut!
spky
Wie ich im Intro zur Antwort sagte: Wenn Sie die Art des Newline-Zeichens kennen, ist dies nützlich. Wenn Sie dies nicht tun, müssen Sie natürlich eine Art Zeichenprüfung implementieren - oder einfach rstrip verwenden. Ich wollte nicht "unfair" sein, sondern nur einen nicht so unbedeutenden Unterschied veranschaulichen, der in manchen Situationen erwägenswert sein könnte.
Stephen Miller
1
Dies funktioniert sowohl für Windows als auch für Linux (etwas teuer mit re sub, wenn Sie nur nach re Lösung suchen)
import re
if re.search("(\\r|)\\n$", line):
line = re.sub("(\\r|)\\n$","", line)
open()
eine Datei mit dem entsprechenden Parameter 'newline = ...' für Ihre Plattform vergessen wurde (universelle Newline-Unterstützung), müssen Sie diese möglicherweise nicht explizit entfernen.Antworten:
Probieren Sie die Methode aus
rstrip()
(siehe Dokument Python 2 und Python 3 ).Die Python-
rstrip()
Methode entfernt standardmäßig alle Arten von nachgestellten Leerzeichen, nicht nur eine neue Zeile, wie dies bei Perl der Fall istchomp
.So entfernen Sie nur Zeilenumbrüche:
Es gibt auch die Methoden
lstrip()
undstrip()
:quelle
\n
für Zeilenumbrüche genau wie Unix. (Vor OS X wurde MacOS\r
als Zeilentrennzeichen verwendet, aber das endete vor 10 Jahren.).strip()
ändert den String nicht (hat wahrscheinlich etwas mit unveränderlichen Strings zu tun). Wenn nicht in der Kommandozeile, wollen Sie"string = string.strip()"
Und ich würde sagen, der "pythonische" Weg, um Zeilen ohne nachgestellte Zeilenumbrüche zu erhalten, ist splitlines ().
quelle
str.splitlines()
Leckereien wie Zeilenumbrüche viele Zeichen (nicht nur\r
,\n
)Die kanonische Methode zum Entfernen von Zeilenendezeichen (EOL) besteht darin, die Methode string rstrip () zu verwenden, um nachfolgende \ r oder \ n zu entfernen. Hier finden Sie Beispiele für Mac-, Windows- und Unix-EOL-Zeichen.
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 oben genannten Fällen.
Diese Nuance ist in seltenen Fällen von Bedeutung. Zum Beispiel musste ich 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 verwendet habe, hat ein 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' entfernt, was nicht das ist, was ich wollte. In diesem Fall habe ich stattdessen einfach die letzten beiden Zeichen abgeschnitten.
Beachten Sie, dass im Gegensatz zu Perls
chomp
Funktion alle angegebenen Zeichen am Ende der Zeichenfolge entfernt werden, nicht nur eines:quelle
os.linesep
die EOL-Sequenz für das aktuelle Betriebssystem.\n
und\r
Beachten Sie, dass rstrip nicht genau wie Perls chomp () funktioniert, da es den String nicht ändert. Das heißt, in Perl:
führt zu
$x
Sein"a"
.aber in Python:
wird bedeuten, dass der Wert von
x
immer noch ist"a\n"
. Auchx=x.rstrip()
gibt nicht immer das gleiche Ergebnis, da alle Leerzeichen vom Ende der Zeichenfolge entfernt werden, nicht nur höchstens eine neue Zeile.quelle
Ich könnte so etwas verwenden:
Ich denke, das Problem dabei
rstrip("\n")
ist, dass Sie wahrscheinlich sicherstellen möchten, dass das Zeilentrennzeichen tragbar ist. (Einige veraltete Systeme sollen verwendet werden"\r\n"
). Das andere Problem ist, dassrstrip
wiederholte Leerzeichen entfernt werden. Hoffentlichos.linesep
enthält die richtigen Zeichen. Das obige funktioniert für mich.quelle
rstrip('\r\n')
undrstrip()
diese entfernt.Sie können verwenden
line = line.rstrip('\n')
. Dadurch werden alle Zeilenumbrüche vom Ende der Zeichenfolge entfernt, nicht nur eine.quelle
entfernt alle Zeilenumbrüche am Ende der Zeichenfolge
s
. Die Zuweisung wird benötigt, darstrip
eine neue Zeichenfolge zurückgegeben wird, anstatt die ursprüngliche Zeichenfolge zu ändern.quelle
Dies würde genau Perls Chomp (minus Verhalten auf Arrays) für den Zeilenabschluss "\ n" replizieren:
(Hinweis: Die Zeichenfolge 'an Ort und Stelle' wird nicht geändert. Es werden keine zusätzlichen nachgestellten Leerzeichen entfernt. Berücksichtigt \ r \ n.)
quelle
oder du könntest mit regulären Ausdrücken immer geekier werden :)
habe Spaß!
quelle
.replace('\n|\r', '')
?import re
re.sub('\n|\r', '', '\nx\n\r\n')
==>'x'
.Sie können Streifen verwenden:
Demo:
quelle
rstrip macht auf so vielen Ebenen nicht dasselbe wie chomp. 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 1 Zeilenende entfernt, während rstrip so viele wie möglich entfernt.
Hier können Sie sehen, wie rstrip alle Zeilenumbrüche entfernt:
Eine viel engere Annäherung an die typische Verwendung von Perl-Chomp kann mit re wie folgt erreicht werden:
quelle
Vorsicht bei
"foo".rstrip(os.linesep)
: Dadurch werden nur die Zeilenumbruchzeichen für die Plattform verarbeitet, auf der Ihr Python ausgeführt wird. Stellen Sie sich vor, Sie schimpfen unter Linux mit den Zeilen einer Windows-Datei, zum Beispiel:Verwenden Sie
"foo".rstrip("\r\n")
stattdessen, wie Mike oben sagt.quelle
chomp
.Ein Beispiel in der Python-Dokumentation verwendet einfach
line.strip()
.Perls
chomp
Funktion entfernt eine Zeilenumbruchsequenz nur dann vom Ende einer Zeichenfolge, wenn sie tatsächlich vorhanden ist.So plane ich das in Python, wenn dies
process
konzeptionell die Funktion ist, die ich benötige, um für jede Zeile aus dieser Datei etwas Nützliches zu tun:quelle
Ich programmiere nicht in Python, aber ich bin auf python.org auf eine FAQ gestoßen, die S.rstrip ("\ r \ n") für Python 2.2 oder höher befürwortet.
quelle
quelle
Ich finde es praktisch, die gechompten Zeilen im Iterator abrufen zu können, parallel zu der Art und Weise, wie Sie die nicht gechompten Zeilen von einem Dateiobjekt abrufen können. Sie können dies mit dem folgenden Code tun:
Beispielnutzung:
quelle
operator.methodcaller
undmap
(itertools.imap
auf Py2) können Sie diese Arbeit auf die C-Ebene übertragen, indem Sie den Code des Python-Level-Generators vermeiden (und dadurch etwas schneller laufen, obwohl der E / A-Overhead zugegebenermaßen kleine Gewinne maskieren kann) :for line in map(operator.methodcaller('rstrip', '\r\n'), infile):
. Es könnte immer noch als herausgerechnet werdendef chomped_lines(it): return map(operator.methodcaller('rstrip', '\r\n'), it)
.Problemumgehungslösung für Sonderfälle:
Wenn das Zeilenumbruchzeichen das letzte Zeichen ist (wie dies bei den meisten Dateieingaben der Fall ist), können Sie für jedes Element in der Sammlung Folgendes indizieren:
um Ihren Newline-Charakter herauszuschneiden.
quelle
Wenn Sie alle Zeilenumbrüche in einem mehrzeiligen str-Objekt (oldstr) bereinigen möchten, können Sie es gemäß dem Trennzeichen '\ n' in eine Liste aufteilen und diese Liste dann zu einem neuen str (newstr) zusammenfügen.
newstr = "".join(oldstr.split('\n'))
quelle
Es sieht so aus, als gäbe es kein perfektes Analogon für Perls Chomp . Insbesondere kann rstrip keine Newline-Trennzeichen mit mehreren Zeichen wie verarbeiten
\r\n
. Allerdings Teilungslinien nicht wie hier darauf hingewiesen . Nach meiner Antwort auf eine andere Frage, können Sie kombinieren beitreten und Teilungslinien entfernen / ersetzen Sie alle Zeilenumbrüche aus einem Strings
:Folgende entfernt genau ein nachlauf Newline (wie chomp würde, glaube ich). Bei
True
derkeepends
Übergabe als Argument an Splitlines bleiben die Trennzeichen erhalten. Dann wird Splitlines erneut aufgerufen, um die Trennzeichen nur in der letzten "Zeile" zu entfernen:quelle
Ich sprudle meine auf regulären Ausdrücken basierende Antwort von einer, die ich zuvor in den Kommentaren einer anderen Antwort gepostet habe. Ich denke, die Verwendung
re
ist eine klarere und explizitere Lösung für dieses Problem alsstr.rstrip
.Wenn Sie ein oder mehrere nachgestellte Zeilenumbrüche entfernen möchten:
Wenn Sie Zeilenumbrüche überall entfernen möchten (nicht nur am Ende):
Wenn Sie nur 1-2 Newline Zeichen (dh entfernen
\r
,\n
,\r\n
,\n\r
,\r\r
,\n\n
)Ich habe das Gefühl, was die meisten Leute hier wirklich wollen, ist, nur ein Vorkommen eines nachgestellten Zeilenumbruchs zu entfernen , entweder
\r\n
oder\n
und nichts weiter.(Das
?:
ist, um eine nicht erfassende Gruppe zu erstellen.)(Übrigens ist dies nicht das, was
'...'.rstrip('\n', '').rstrip('\r', '')
für andere, die über diesen Thread stolpern, möglicherweise nicht klar ist.str.rstrip
Entfernt so viele der nachfolgenden Zeichen wie möglich, sodass eine Zeichenfolge wiefoo\n\n\n
ein falsches Positiv von ergibt,foo
während Sie möglicherweise die beibehalten möchten andere Zeilenumbrüche nach dem Entfernen eines einzelnen nachfolgenden.)quelle
r'\r?\n$'
. Wahrscheinlich effizienter, da es für Regex-Motoren schwieriger ist, Wechsel zu optimieren. Beachten Sie auch, dass der Ausdruck , wenn Sie dies mehrmals tunre
,re.compile
im Vorfeld erheblich schneller ist (insbesondere, wenn Sie sich mit anderen Verwendungszwecken vermischen). Verwenden Sie dann diesub
Methode des kompilierten regulären Ausdrucksobjekts . Modulfunktionen sind auf Python-Ebene und überprüfen zuerst einen Cache auf kompilierte reguläre Ausdrücke (Erstellen / Zwischenspeichern, falls nicht vorhanden) und rufen dann die Matching-Methode auf. Das Überspringen dieser Suche hilft.\n
direkt abzugleichen , möchten Sie möglicherweise\Z
over verwenden$
(oder einfach nur übereinstimmen\r?$
, da$
implizit kurz vor der neuen Zeile am Ende eines Strings übereinstimmen kann).quelle
"\r\n"
Zum Beispiel:' spacious \n\r\n\r \n\n'.rstrip()
produziert' spacious'
Benutz einfach :
oder
Sie brauchen nichts von diesem komplizierten Zeug
quelle
Mit Regex
Ersetzen Sie \ n, \ t, \ r
Mit Regex
mit Join
quelle
Es gibt drei Arten von Zeilenenden , dass wir normalerweise auftreten:
\n
,\r
und\r\n
. Ein ziemlich einfacher regulärer Ausdruck inre.sub
nämlichr"\r?\n?$"
kann sie alle fangen.(Und wir müssen sie alle fangen , habe ich recht?)
Mit dem letzten Argument begrenzen wir die Anzahl der ersetzten Vorkommen auf eins und ahmen Chomp bis zu einem gewissen Grad nach. Beispiel:
... wo
a == b == c
istTrue
.quelle
rstrip("\r\n")
ist ein Allheilmittel. Versuchen Sie esprint(text_2.rstrip('\r\n'))
.str.rstrip()
das Problem löst. Es hängt davon ab, welche Bedürfnisse Sie haben. Diese Lösung wird für die Fälle speziell gemacht , wenn Sie nur die letzte entfernen müssen"\n"
,"\r"
oder"\r\n"
aber nicht alle von ihnen (wenn es mehrere sind"\n"
in der Zeichenfolge).re.sub(r"\r?\n?$", "", text_1, 1)
gibt zurück"hellothere\n\n"
und gibttext_1.rstrip("\r\n")
zurück,"hellothere"
was eine andere Zeichenfolge ist.str.strip()
ist ein Allheilmittel, manchmal ist es genau das Problem.Wenn Sie sich Gedanken über die Geschwindigkeit machen (sagen wir, Sie haben eine lange Liste von Zeichenfolgen) und die Art des Newline-Zeichens kennen, ist das Schneiden von Zeichenfolgen tatsächlich schneller als rstrip. Ein kleiner Test, um dies zu veranschaulichen:
Ausgabe:
quelle
method1
Sie hacken nur das letzte Zeichen ab, egal was passiert, beimethod2
den.rstrip()
ersten Überprüfungen, ob das Ende des Strings unerwünschte Zeichen enthält und sie abhackt, nur wenn einige gefunden wurden. Bitte überprüfen Sie die Zeichenmethod1
und testen Sie sie erneut!Dies funktioniert sowohl für Windows als auch für Linux (etwas teuer mit re sub, wenn Sie nur nach re Lösung suchen)
quelle
re.search
wo Sie es gerade brauchenre.sub
?Trennen Sie zuerst die Linien und verbinden Sie sie dann mit einem beliebigen Trennzeichen:
sollte wie ein Zauber wirken.
quelle
Ein Haken an alle:
quelle
rstrip
nimmt keinen regulären Ausdruck."hi|||\n\n".rstrip("\r|\n")
Rückkehr"hi"