如何在Python中删除尾部换行符?

1593 python newline trailing

什么是Perl chomp函数的Python等价物,如果它是换行符,它会删除字符串的最后一个字符?

Ric*_*haw 1744

尝试该方法rstrip()(参见文档Python 2Python 3)

>>> 'test string\n'.rstrip()
'test string'
Run Code Online (Sandbox Code Playgroud)

Python的rstrip()方法默认情况下会删除所有类型的尾随空格,而不仅仅是Perl所做的一个新行chomp.

>>> 'test string \n \r\n\n\r \n\n'.rstrip()
'test string'
Run Code Online (Sandbox Code Playgroud)

仅删除换行符:

>>> 'test string \n \r\n\n\r \n\n'.rstrip('\n')
'test string \n \r\n\n\r '
Run Code Online (Sandbox Code Playgroud)

还有方法lstrip()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'
Run Code Online (Sandbox Code Playgroud)

  • 我不是Python人,所以我没有答案,但Perl的chomp()实际上从最后删除了输入记录分隔符.这是关于Unixy事物的新线,但可能不同(例如Windows)并且它是可变的.有没有办法从字符串的末尾只删除一次该值? (21认同)
  • @briandfoy Python内置了对Universal换行的支持(仅在阅读时,而不是在写作时).您可以在"U"或"rU"模式下打开文件,然后无论Windows,Linux,Mac等等,在文本到达您的python代码时,任何样式的换行都已替换为"\n".请参阅:http://www.python.org/dev/peps/pep-0278/ (18认同)
  • @csde_rats,这不是真的:OS X像Unix一样使用`\n`来换行.(在OS X之前,MacOS确实使用`\ r`作为行分隔符,但是在10年前结束了.) (6认同)
  • 我要继续拼出来,因为我是一个菜鸟,我花了一段时间想知道它为什么不起作用.`.strip()`不会改变字符串(可能与不可变字符串有关).如果不在命令行中,你会想要``string = string.strip()"` (6认同)
  • brian d foy:Python没有像awk和Perl那样的输入记录分隔符. (5认同)
  • 是否足够?>>>"test string\r \n".rstrip("\n")'test string\r' (4认同)
  • @AlixAxel如上所述@AlcubierreDrive,以便携方式处理换行意味着当从文件中读取它们时,它们将转换为规范的`\n`形式.然后,使用字符串的程序永远不会看到`\ r`字符. (3认同)
  • @yegle,我认为你的意思是'ded',而不是'def'.:) (2认同)
  • 如果您使用一些空列处理TSV,rstrip()本身会给您带来很多麻烦.例如,"foo\tbar\t\t \n".rstrip()将从数据中删除最后两个空列. (2认同)

Rya*_*rom 153

而且我会说"pythonic"获取没有尾随换行符的行的方法是splitlines().

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

  • 如果您使用fd.readlines()等,则不会. (5认同)
  • 注意:[`str.splitlines()`将换行视为换行符(不仅仅是`\ r`,`\n`)](https://docs.python.org/3/library/stdtypes.html#str. splitlines) (4认同)

Mik*_*ike 140

剥离行尾(EOL)字符的规范方法是使用字符串rstrip()方法删除任何尾部\ r或\n.以下是Mac,Windows和Unix EOL字符的示例.

>>> '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'
Run Code Online (Sandbox Code Playgroud)

使用'\ r \n'作为rstrip的参数意味着它将删除'\ r'或'\n'的任何尾随组合.这就是为什么它适用于上述所有三种情况.

这种细微差别在极少数情况下很重要 例如,我曾经不得不处理一个包含HL7消息的文本文件.HL7标准要求尾随'\n'作为其EOL字符.我使用此消息的Windows机器附加了自己的'\ r \n'EOL字符.因此,每行的结尾看起来像'\ r \n\r \n'.使用rstrip('\ r \n')会取消整个'\ r \n \n \n',这不是我想要的.在那种情况下,我只是将最后两个字符切掉.

请注意,与Perl的chomp函数不同,这将删除字符串末尾的所有指定字符,而不仅仅是一个:

>>> "Hello\n\n\n".rstrip("\n")
"Hello"
Run Code Online (Sandbox Code Playgroud)

  • 还有[`os.linesep`](http://docs.python.org/library/os.html#os.linesep),其中包含当前操作系统的EOL序列. (12认同)
  • 请注意,现代Mac OS X应用程序使用\n.只有最初为Mac OS编写的旧Carbon应用才使用\ r \n. (7认同)
  • 谢谢你的澄清.当然,rstrip('\ r \n')在这种情况下仍然有效. (2认同)

小智 98

请注意,rstrip的行为与Perl的chomp()完全不同,因为它不会修改字符串.也就是说,在Perl中:

$x="a\n";

chomp $x
Run Code Online (Sandbox Code Playgroud)

导致$x存在"a".

但在Python中:

x="a\n"

x.rstrip()
Run Code Online (Sandbox Code Playgroud)

将意味着价值x依旧 "a\n".甚至x=x.rstrip()并不总是给出相同的结果,因为它从字符串的末尾剥离所有空格,而不是最多只有一个换行符.

  • 啊,是的,字符串是不可变的,谢谢提醒! (10认同)
  • 另外,strip()删除重复的字符,而chop/chomp只删除一个换行符 (6认同)

小智 49

我可能会使用这样的东西:

import os
s = s.rstrip(os.linesep)
Run Code Online (Sandbox Code Playgroud)

我认为问题rstrip("\n")在于您可能希望确保行分隔符是可移植的.(据传有些过时的系统使用"\r\n").另一个问题是rstrip将删除重复的空格.希望os.linesep包含正确的字符.以上对我有用.

  • 但是,如果您尝试在Web应用程序中清理用户提交的内容,则无法使用此功能.用户内容可以来自任何来源并包含任何换行符. (12认同)
  • 好点,除了您可能正在现代操作系统上处理“外国”文件(来自过时的系统)。 (2认同)

kir*_*off 40

你可以用line = line.rstrip('\n').这将从字符串的末尾删除所有换行符,而不仅仅是一行.


sle*_*lec 34

s = s.rstrip()
Run Code Online (Sandbox Code Playgroud)

将删除字符串末尾的所有换行符s.需要赋值,因为rstrip返回一个新字符串而不是修改原始字符串.


Ali*_*orm 29

这将为"\n"行终止符完全复制perl的chomp(减去数组上的行为):

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

(注意:它不会修改字符串'in place';它不会删除额外的尾随空格;在帐户中取\ r \n)


Hac*_*lic 26

你可以使用strip:

line = line.strip()
Run Code Online (Sandbox Code Playgroud)

演示:

>>> "\n\n hello world \n\n".strip()
'hello world'
Run Code Online (Sandbox Code Playgroud)


mih*_*icc 25

"line 1\nline 2\r\n...".replace('\n', '').replace('\r', '')
>>> 'line 1line 2...'
Run Code Online (Sandbox Code Playgroud)

或者你可以随时使用regexps :)

玩得开心!

  • 为什么不使用一个替换语句,如`.replace('\n |\r','')`? (2认同)
  • 为了防止其他人想要使用@DoorknobofSnow的想法,使用正则表达式模块只是一个小小的改动:`import re``re.sub('\n |\r','','\n \n \n \n \n\r \n')`==>`'x'`. (2认同)

Car*_*nte 19

小心"foo".rstrip(os.linesep):这只会扼杀正在执行Python的平台的换行符.想象一下,你正在Linux下使用Windows文件的行,例如:

$ 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'
>>>
Run Code Online (Sandbox Code Playgroud)

使用"foo".rstrip("\r\n")替代,如麦克上述表示.


min*_*ret 19

Python文档中的一个例子就是使用line.strip().

Perl的chomp函数只有在字符串结尾处才会删除一个换行序列.

以下是我计划在Python中执行此操作的方法,如果process概念上是我需要的功能,以便对此文件中的每一行执行有用的操作:

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)
Run Code Online (Sandbox Code Playgroud)

  • 最后,答案只删除它***(就像实际的chomp ...)并且是OS便携式的! (2认同)

ing*_*net 17

在很多层面上,rstrip与chomp不同.阅读http://perldoc.perl.org/functions/chomp.html,看看chomp确实非常复杂.

但是,我的主要观点是chomp最多删除1行结束,而rstrip将删除尽可能多的行.

在这里你可以看到删除所有新行的rstrip:

>>> 'foo\n\n'.rstrip(os.linesep)
'foo'
Run Code Online (Sandbox Code Playgroud)

使用re.sub可以更加接近典型的Perl chomp用法,如下所示:

>>> re.sub(os.linesep + r'\Z','','foo\n\n')
'foo\n'
Run Code Online (Sandbox Code Playgroud)

  • 荣誉,您是唯一指出这一重要细节的人。但是,如上所述,如果您正在从其他系统读取文件,则无法使用os.linesep。在Python中,这可能需要更多的工作,实际上是在检查行尾。 (2认同)

And*_*imm 13

我不用Python编程,但是我在python.org上遇到了一个常见问题解答,主张用于python 2.2或更高版本的S.rstrip("\ r \n").


小智 10

import re

r_unwanted = re.compile("[\n\t\r]")
r_unwanted.sub("", your_text)
Run Code Online (Sandbox Code Playgroud)

  • 这也将删除原始问题未请求的制表符空格.(由于\ t字符) (2认同)

Leo*_*ozj 8

如果您的问题是清除多行str对象(oldstr)中的所有换行符,则可以根据分隔符'\n'将其拆分为列表,然后将此列表连接到新的str(newstr).

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


kuz*_*roo 8

我发现能够通过迭代器获取chomped行很方便,与从文件对象中获取未选择行的方式并行.您可以使用以下代码执行此操作:

def chomped_lines(it):
    return map(operator.methodcaller('rstrip', '\r\n'), it)
Run Code Online (Sandbox Code Playgroud)

样品用法:

with open("file.txt") as infile:
    for line in chomped_lines(infile):
        process(line)
Run Code Online (Sandbox Code Playgroud)


小智 7

解决特殊情况的解决方案:

如果换行符是最后一个字符(与大多数文件输入的情况一样),那么对于集合中的任何元素,您可以索引如下:

foobar= foobar[:-1]
Run Code Online (Sandbox Code Playgroud)

切出你的换行符.

  • 有时换行符不是最后一个字符,而是最后一个字符,特别是在Windows上,正如其他人指出的那样。 (3认同)

use*_*389 7

看起来perl的chomp没有完美的模拟.特别是,rstrip无法处理多字符换行分隔符\r\n.然而,splitlines不会因为在这里指出.根据对其他问题的回答,您可以组合连接拆分线以从字符串中删除/替换所有换行符s:

''.join(s.splitlines())
Run Code Online (Sandbox Code Playgroud)

以下删除了一个尾随换行符(我相信chomp会这样).True作为keepends分裂线的参数传递保留分隔符.然后,再次调用splitlines以删除最后一行"分隔符":

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


Tay*_*ton 6

我正在鼓励我从前面在另一个答案的评论中发布的一个基于正则表达式的答案.我认为使用re是比这个问题更清晰,更明确的解决方案str.rstrip.

>>> import re
Run Code Online (Sandbox Code Playgroud)

如果要删除一个或多个尾随换行符:

>>> re.sub(r'[\n\r]+$', '', '\nx\r\n')
'\nx'
Run Code Online (Sandbox Code Playgroud)

如果你想删除所有地方的换行符(不仅仅是尾随):

>>> re.sub(r'[\n\r]+', '', '\nx\r\n')
'x'
Run Code Online (Sandbox Code Playgroud)

如果你想删除只有1-2换行符字符(即\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'
Run Code Online (Sandbox Code Playgroud)

我有一种感觉,大多数人真的想在这里,是消除只是一个发生尾随换行符的,无论是\r\n\n仅此而已.

>>> 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'
Run Code Online (Sandbox Code Playgroud)

(这?:是创建一个非捕获组.)

(顺便说一下,这是不是有什么'...'.rstrip('\n', '').rstrip('\r', '')不这可能不是很清楚别人绊倒在这个线程. str.rstrip带尽可能多的拖尾字符越好,因此喜欢的字符串foo\n\n\n会导致假阳性的foo,而你可能想保留剥离单个尾随后的其他换行符.)


小智 6

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'
Run Code Online (Sandbox Code Playgroud)

使用正则表达式

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

替换\n,\t,\r

s.replace('\n', '').replace('\t','').replace('\r','')
>'  Hello  World Hi '
Run Code Online (Sandbox Code Playgroud)

使用正则表达式

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

与加入

s = '''Hello  World \t\n\r\tHi There'''
' '.join(s.split())
>'Hello  World Hi There'
Run Code Online (Sandbox Code Playgroud)


小智 5

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

  • @olibre 您建议的代码还将删除其他空白/空格字符,这可能不是人们所需要的。事实上,我只需要剥离 eol 字符的组合。不过,感谢您指出这一点。 (2认同)