如何删除尾随换行符?

如果字符串是换行符,如何删除字符串的最后一个字符?

"abc\n"  -->  "abc"
2276409 次浏览

尝试方法rstrip()(见文档python2python3

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

默认情况下,Python的rstrip()方法去掉了所有种尾随空格,而不是像Perl对#1那样只去掉一个换行符。

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

仅删除换行符:

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

除了rstrip()之外,还有方法strip()lstrip()。这是其中三个的示例:

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

删除行尾(EOL)字符的规范方法是使用字符串r的()方法删除任何尾随\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'

使用'\r\n'作为参数来r的意思是它将去掉'\r'或'\n'的任何尾随组合。这就是为什么它适用于上述所有三种情况。

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

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

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

我会说“pythonic”的方式来获得行没有尾随换行符是拆分线()。

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

请注意,r的行为并不完全像Perl的chomp(),因为它不会修改字符串。也就是说,在Perl中:

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

结果$x"a"

但在Python中:

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

将意味着x的值是仍然"a\n"。即使是x=x.rstrip()也不总是给出相同的结果,因为它从字符串末尾删除了所有空格,而不仅仅是一个换行符。

我不使用Python编程,但我在python.org遇到了一个FAQ,提倡Python 2.2或更高版本的S.rstrip(“\r\n”)。

我可以使用这样的东西:

import oss = s.rstrip(os.linesep)

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

在很多层面上,rStrie与chomp做的事情不一样。阅读http://perldoc.perl.org/functions/chomp.html并看到chomp确实非常复杂。

然而,我的主要观点是,chomp最多删除1行结尾,而r地带将尽可能多地删除。

在这里你可以看到删除所有换行符:

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

典型的Perl chomp用法的更接近可以通过re.sub来完成,如下所示:

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

小心"foo".rstrip(os.linesep):这只会在执行Python的平台上删除换行符。想象一下,您将Windows文件的行嵌合在Linux下,例如:

$ pythonPython 2.7.1 (r271:86832, Mar 18 2011, 09:09:48)[GCC 4.5.0 20100604 [gcc-4_5-branch revision 160292]] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> import os, sys>>> sys.platform'linux2'>>> "foo\r\n".rstrip(os.linesep)'foo\r'>>>

使用"foo".rstrip("\r\n")代替,正如Mike上面所说。

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

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

foobar= foobar[:-1]

切出您的换行符。

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

或者你可以用regexps变得更怪

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

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

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

Python留档中的示例只是使用line.strip()

Perl的chomp函数仅在字符串末尾实际存在时才从字符串末尾删除一个换行符序列。

这是我计划在Python中这样做的方式,如果process在概念上是我需要的函数,以便对该文件中的每一行做一些有用的事情:

import ossep_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)
import re
r_unwanted = re.compile("[\n\t\r]")r_unwanted.sub("", your_text)

一个捕获所有:

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

您可以使用条:

line = line.strip()

demo:

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

我发现能够通过迭代器获取咬合行很方便,与从文件对象获取未咬合行的方式平行。你可以使用以下代码做到这一点:

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

样品用法:

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

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

这将完全复制perl对“\n”行终止符的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

(注意:它不会修改字符串'in place';它不会去掉额外的尾随空格;考虑\r\n)

如果你关心速度(假设你有一个很长的字符串列表),并且你知道换行符char的性质,字符串切片实际上比r的快。一个小测试来说明这一点:

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

输出:

Method 1: 3.92700004578Method 2: 6.73000001907

只需使用:

line = line.rstrip("\n")

line = line.strip("\n")

你不需要这些复杂的东西

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

我们通常会遇到三种类型的行尾:\n\r\r\n#3中的一个相当简单的正则表达式,即r"\r?\n?$",能够捕获它们。

(我们把他们都抓起来,对吗?)

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

使用最后一个参数,我们将替换的出现次数限制为一个,在某种程度上模仿了chomp。例子:

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)

…其中a == b == cTrue

看起来Perl的咀嚼没有完美的模拟。特别是,r的不能处理像\r\n这样的多字符换行符分隔符。然而,分割线做了正如这里所指出的。在不同问题的我的答案之后,您可以组合加入分割线来删除/替换字符串s中的所有换行符:

''.join(s.splitlines())

以下内容删除了只有一个尾随换行符(我相信就像chomp一样)。将True作为keepends参数传递给拆分线保留分隔符。然后,再次调用拆分线以删除最后一行的分隔符:

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

我正在冒泡我之前在另一个答案的评论中发布的基于正则表达式的答案。我认为使用restr.rstrip更清楚地解决这个问题。

>>> import re

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

>>> re.sub(r'[\n\r]+$', '', '\nx\r\n')'\nx'

如果你想到处删除换行符(不仅仅是尾随):

>>> re.sub(r'[\n\r]+', '', '\nx\r\n')'x'

如果您只想删除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'

我有一种感觉,大多数人真正想要的是删除尾随换行符的一个出现,\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'

?:是创建一个非捕获组。)

(顺便说一句,这是没有'...'.rstrip('\n', '').rstrip('\r', '')所做的,可能不清楚其他人偶然发现这个线程.str.rstrip剥离尽可能多的尾随字符,所以像foo\n\n\n这样的字符串会导致foo的误报,而您可能希望在剥离单个尾随字符后保留其他换行符。


这将适用于windows和linux(如果您只寻找re解决方案,re sub有点贵)

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

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

与regex

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

替换\n,\t,\r

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

与regex

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

与加入

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