Hoe kan ik een afsluitende nieuwe regel verwijderen?

Wat is het Python-equivalent van Perl’s chomp-functie, die het laatste teken van een string verwijdert als het een nieuwe regel is?


Antwoord 1, autoriteit 100%

Probeer de methode rstrip()(zie doc Python 2en Python 3)

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

Python’s rstrip()methode verwijdert standaard allesoorten witruimte, niet slechts één nieuwe regel zoals Perl doet met chomp.

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

Alleen nieuwe regels verwijderen:

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

Er zijn ook de methoden strip(), lstrip()en 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'

Antwoord 2, autoriteit 8%

En ik zou zeggen dat de “pythonische” manier om regels te krijgen zonder nieuwe regeltekens te volgen, splitlines() is.

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

Antwoord 3, autoriteit 8%

De canonieke manier om end-of-line (EOL)-tekens te verwijderen, is door de string rstrip()-methode te gebruiken, waarbij eventuele \r of \n aan het einde wordt verwijderd. Hier zijn voorbeelden voor Mac-, Windows- en Unix EOL-tekens.

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

Het gebruik van ‘\r\n’ als parameter voor rstrip betekent dat het elke volgende combinatie van ‘\r’ of ‘\n’ verwijdert. Daarom werkt het in alle drie de bovenstaande gevallen.

Deze nuance is in zeldzame gevallen van belang. Zo moest ik ooit een tekstbestand verwerken waarin een HL7-bericht stond. De HL7-standaard vereist een afsluitende ‘\r’ als EOL-teken. De Windows-machine waarop ik dit bericht gebruikte, had een eigen ‘\r\n’ EOL-teken toegevoegd. Daarom zag het einde van elke regel eruit als ‘\r\r\n’. Het gebruik van rstrip(‘\r\n’) zou de hele ‘\r\r\n’ hebben verwijderd, wat niet is wat ik wilde. In dat geval heb ik in plaats daarvan gewoon de laatste twee tekens weggesneden.

Merk op dat, in tegenstelling tot de functie chompvan Perl, dit alle opgegeven tekens aan het einde van de tekenreeks verwijdert, niet slechts één:

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

Antwoord 4, autoriteit 5%

Merk op dat rstrip niet precies hetzelfde werkt als Perl’s chomp() omdat het de string niet wijzigt. Dat wil zeggen, in Perl:

$x="a\n";
chomp $x

resulteert in dat $x"a"is.

maar in Python:

x="a\n"
x.rstrip()

betekent dat de waarde van xstill"a\n"is. Zelfs x=x.rstrip()geeft niet altijd hetzelfde resultaat, omdat het alle witruimte vanaf het einde van de string verwijdert, niet slechts één nieuwe regel.


Antwoord 5, autoriteit 2%

Ik zou zoiets als dit kunnen gebruiken:

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

Ik denk dat het probleem met rstrip("\n")is dat je er waarschijnlijk zeker van wilt zijn dat het regelscheidingsteken draagbaar is. (sommige verouderde systemen gebruiken naar verluidt "\r\n"). Het andere probleem is dat rstripherhaalde witruimte zal verwijderen. Hopelijk bevat os.linesepde juiste karakters. het bovenstaande werkt voor mij.


Antwoord 6, autoriteit 2%

Je mag line = line.rstrip('\n')gebruiken. Hiermee worden alle nieuwe regels vanaf het einde van de tekenreeks verwijderd, niet slechts één.


Antwoord 7, autoriteit 2%

s = s.rstrip()

verwijdert alle nieuwe regels aan het einde van de tekenreeks s. De toewijzing is nodig omdat rstripeen nieuwe tekenreeks retourneert in plaats van de oorspronkelijke tekenreeks te wijzigen.


Antwoord 8, autoriteit 2%

Dit zou exact de chomp van perl (minus gedrag op arrays) repliceren voor “\n” regelterminator:

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

(Opmerking: het wijzigt de tekenreeks ‘op zijn plaats’ niet; het verwijdert geen extra witruimte aan het einde; houdt rekening met \r\n)


Antwoord 9

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

of je kunt altijd geekier krijgen met Regexps 🙂

Veel plezier!


10

U kunt strip gebruiken:

line = line.strip()

Demo:

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

11

Rstrip doet niet hetzelfde als Chomp, op zoveel niveaus. Lees http://perldoc.perl.org/functions/chomp.html en zie dat Chomp is inderdaad erg complex.

Mijn hoofdpunt is echter dat Chomp maximaal 1 lijn eindigt, terwijl Rstrip zoveel mogelijk zal verwijderen.

Hier kunt u Rstrip zien verwijderen van alle newlines:

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

Een veel dichter bij benadering van het typische Perl Chomp-gebruik kan worden bereikt met Re.Sub, zoals deze:

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

12

Voorzichtig met "foo".rstrip(os.linesep): dat zal alleen de nieuwlijnpersonages kiezen voor het platform waar uw Python wordt uitgevoerd. Stel je voor dat je de regels van een Windows-bestand onder Linux kunt cirkelen, bijvoorbeeld:

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

Gebruik "foo".rstrip("\r\n")in plaats daarvan, zoals Mike hierboven zegt.


13

een voorbeeld in de documentatie van Python gebruikt eenvoudig line.strip().

PERL’s chompFUNCTION Verwijdert één lineBreak-sequentie van het einde van een reeks alleen als het daar eigenlijk is.

Hier is hoe ik dat in Python wil doen, als processconceptueel de functie is die ik nodig heb om iets nuttigs te doen voor elke regel uit dit bestand:

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)

14

Ik programmeer niet in Python, maar ik kwam een ​​FAQ bij Python.org pleiten voor s.rstrip (” \ r \ r \ n “) voor Python 2.2 of hoger.


15

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

16

Als uw vraag is om alle lijnbrekes op te ruimen in een meervoudige lijnstrobject (Oldstr), kunt u deze in een lijst opsplitsen volgens de scheidingsteken ‘\ N’ en vervolgens aanmelden bij deze lijst in een nieuwe str (Newtr ).

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


17

Ik vind het handig om de gechompte regels via de iterator te kunnen krijgen, parallel aan de manier waarop je de niet-gechompte regels uit een bestandsobject kunt halen. U kunt dit doen met de volgende code:

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

Voorbeeldgebruik:

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

18

Workaround-oplossing voor speciaal geval:

Als het nieuwe lijnteken het laatste teken is (zoals het geval is met de meeste bestandsinvoer), dan voor elk element in de verzameling kunt u als volgt indexeren:

foobar= foobar[:-1]

om uw nieuwe lijnteken te plakken.


19

Het lijkt erop dat er geen perfecte analoge is voor Perl’s chomp . In het bijzonder, rstrip kan geen multi-personage newline-delimiters zoals \r\n. Echter, splitlines doet Agen wees hier .
Volgend Mijn antwoord op een andere vraag, kunt u Word lid en Slitlines om alle newlines uit een string te verwijderen / vervangen s:

''.join(s.splitlines())

Het volgende verwijdert precies één trailing newline (zoals chomp zou, geloof ik). Doorgeven TrueZoals de keependsARGUMENT VOOR SLAPLINES BEHOUDEN DE DELIMITERS. Vervolgens wordt Slitlines opnieuw gebeld om de scheidingstekens te verwijderen op slechts de laatste “LINE”:

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

20

s = '''Hello  World \t\n\r\tHi There'''
# import the module string   
import string
# use the method translate to convert 
s.translate({ord(c): None for c in string.whitespace}
>>'HelloWorldHiThere'

Met regex

s = '''  Hello  World 
\t\n\r\tHi '''
print(re.sub(r"\s+", "", s), sep='')  # \s matches all white spaces
>HelloWorldHi

Vervang \n,\t,\r

s.replace('\n', '').replace('\t','').replace('\r','')
>'  Hello  World Hi '

Met regex

s = '''Hello  World \t\n\r\tHi There'''
regex = re.compile(r'[\n\r\t]')
regex.sub("", s)
>'Hello  World Hi There'

met Join

s = '''Hello  World \t\n\r\tHi There'''
' '.join(s.split())
>'Hello  World Hi There'

Antwoord 21

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

Antwoord 22

Gebruik gewoon:

line = line.rstrip("\n")

of

line = line.strip("\n")

Je hebt geen van deze ingewikkelde dingen nodig


Antwoord 23

Er zijn drie soorten regeleindes die we normaal tegenkomen: \n, \ren \r\n. Een vrij eenvoudige reguliere expressie in re.sub, namelijk r"\r?\n?$", kan ze allemaal vangen.

(En we moeten ze allemaal vangen, heb ik gelijk?)

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

Met het laatste argument beperken we het aantal voorkomens voorkomende gebeurtenissen, het mimsten van Chomp op zekere hoogte. Voorbeeld:

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)

… waar a == b == cis True.


24

Als u zich zorgen maakt over de snelheid (zeg dat u een loong-lijst met snaren hebt) en u weet dat de aard van de Newline Char, is String Snelling eigenlijk sneller dan Rstrip. Een kleine test om dit te illustreren:

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

Uitgang:

Method 1: 3.92700004578
Method 2: 6.73000001907

25


Dit werkt zowel voor Windows als Linux (bit duur bij RE-sub als u op zoek bent naar alleen re-oplossing)

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


26

Een vangst:

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

Other episodes