verlängern - write zeilenumbruch python




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

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


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.


Benutz einfach :

line = line.rstrip("\n")

oder

line = line.strip("\n")

Sie brauchen keine dieser komplizierten Sachen


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)


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)

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 .


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


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.


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

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

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

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

So entfernen Sie nur Zeilenumbrüche:

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

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


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.


Und ich würde sagen, die "pythonische" Art, Zeilen ohne nachfolgende Zeilenumbruchzeichen zu erhalten, ist Splitlines ().

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

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


Wenn Sie sich Gedanken über die Geschwindigkeit machen (sagen Sie, Sie haben eine lange Liste von Strings) und Sie wissen, die Art der Newline Char, String-Slicing ist tatsächlich schneller als rstrip. Ein kleiner Test, um dies zu verdeutlichen:

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

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

oder du könntest immer mit Regexps geekier werden :)

habe Spaß!


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

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