Wie kann ich eine nachfolgende neue Zeile in Python entfernen(chomp)?




write zeilenumbruch python (20)

Was ist das Python-Äquivalent von Perls chomp Funktion, die das letzte Zeichen eines Strings entfernt, wenn es sich um einen Zeilenumbruch handelt?


Ein Beispiel in Pythons Dokumentation verwendet einfach line.strip() .

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

Hier ist, wie ich das in Python tun möchte, wenn der process konzeptionell die Funktion ist, die ich brauche, um etwas Nützliches für jede Zeile aus dieser Datei 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)

Beachten Sie, dass rstrip nicht genau wie Perls chomp () funktioniert, da die Zeichenfolge nicht geändert wird. Das heißt, in Perl:

$x="a\n";

chomp $x

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

aber in Python:

x="a\n"

x.rstrip()

wird bedeuten, dass der Wert von x immer noch "a\n" . Sogar x=x.rstrip() liefert nicht immer das gleiche Ergebnis, da es alle Whitespaces vom Ende des Strings entfernt und nicht nur einen Newline-String.


Ein Fang alle:

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

Sie können Streifen verwenden:

line = line.strip()

Demo:

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

rstrip macht auf vielen Ebenen nicht dasselbe wie chomp. Lies chomp und sieh, dass das Chomp wirklich 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:

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

Eine viel genauere Annäherung der typischen Perl-chomp-Verwendung kann mit re & sub2; wie folgt erreicht werden:

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

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

import re

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

Umgehungslösung für Spezialfälle:

Wenn das Newline-Zeichen das letzte Zeichen ist (wie es bei den meisten Dateieingaben der Fall ist), können Sie für jedes Element in der Sammlung folgendermaßen indizieren:

foobar= foobar[:-1]

um deinen Newline-Charakter auszuschneiden.


Ich finde es bequem, in der Lage zu sein, die chomped Zeilen durch in Iterator zu erhalten, parallel zu der Weise, wie Sie die nicht-chomped 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)

Beispielverwendung:

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

Vorsicht mit "foo".rstrip(os.linesep) : Das wird nur die Newline-Zeichen für die Plattform chompsen, auf der Python ausgeführt wird. Stellen Sie sich vor, Sie würden die Zeilen einer Windows-Datei unter Linux ansprechen:

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

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


Es gibt drei Arten von Zeilenendungen, auf die wir normalerweise stoßen: \n , \r und \r\n . Ein ziemlich einfacher regulärer Ausdruck in re.sub , nämlich r"\r?\n?$" , re.sub in der Lage, sie alle zu re.sub .

(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 Ersetzungen auf eins und imitieren gewissermaßen chomp. 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)

... wo a == b == c ist True .


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 Zeilentrennzeichen tragbar ist. (Einige antiquierte Systeme werden gemunkelt, um "\r\n" ). Die andere Sache ist, dass rstrip wiederholt Leerzeichen rstrip . Hoffentlich enthält os.linesep die richtigen Zeichen. das obige funktioniert für mich.


Benutz einfach :

line = line.rstrip("\n")

oder

line = line.strip("\n")

Sie brauchen keine dieser komplizierten Sachen


Es sieht so aus, als gäbe es kein perfektes Analogon für chomp . Insbesondere kann rstrip keine Multiline -Zeilentrennzeichen wie \r\n . Splitlines funktioniert jedoch wie hier ausgeführt . Im Anschluss an meine Antwort auf eine andere Frage können Sie join und Splitlines kombinieren, um alle Zeilenumbrüche aus einer Zeichenfolge zu entfernen oder zu ersetzen:

''.join(s.splitlines())

Das folgende entfernt genau einen abschließenden Newline (wie chomp würde, glaube ich). Wenn True übergeben wird, behält das Argument keepends für Trennlinien die Trennzeichen bei. Dann wird Splitlines erneut aufgerufen, um die Begrenzer nur auf 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 ''

Ich programmiere nicht in Python, aber ich stieß auf eine FAQ auf python.org, die S.rstrip ("\ r \ n") für Python 2.2 oder höher befürwortet.


Dies würde genau den Chomp (Minus-Verhalten auf Arrays) von Perl für den Zeilenabschluss "\ n" replizieren:

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

(Hinweis: Die Zeichenfolge wird nicht an Ort und Stelle geändert; zusätzliche Leerzeichen werden nicht entfernt. Take \ r \ n berücksichtigt)


Wenn Ihre Frage darin besteht, alle Zeilenumbrüche in einem mehrzeiligen str-Objekt (oldstr) zu bereinigen, können Sie sie in eine Liste entsprechend dem Trennzeichen '\ n' aufteilen und dann dieser Liste in ein neues str (newstr) beifügen.

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


Die kanonische Methode zum Entfernen von End-of-Line-Zeichen (EOL-Zeichen) besteht darin, die string rstrip () -Methode zu verwenden, die alle abschließenden Zeichen (\ r oder \ n) entfernt. Hier finden Sie Beispiele für Mac-, Windows- und Unix-EOL-Zeichen.

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

Wenn Sie '\ r \ n' als Parameter für rstrip verwenden, werden alle nachfolgenden Kombinationen von '\ r' oder '\ n' entfernt. Deshalb funktioniert es in allen drei oben genannten Fällen.

Diese Nuance ist in seltenen Fällen wichtig. 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 verwendete, hatte sein eigenes '\ r \ n' EOL-Zeichen 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 einfach die letzten zwei Zeichen abgeschnitten.

Beachten Sie, dass im Gegensatz zu Perls chomp Funktion alle angegebenen Zeichen am Ende der Zeichenfolge entfernt werden, nicht nur eine:

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

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


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 rstrip .





trailing