我如何删除(chomp)Python中的换行符?

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

尝试方法rstrip() (请参阅文档Python 2和Python 3 )

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

Python的rstrip()方法默认剥离了所有types的尾随空白,而不是像Perl对chomp所做的一样。

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

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

我会说“pythonic”的方式来获得没有拖尾换行符的行是splitlines()。

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

剥离结束符(EOL)字符的规范方法是使用stringrstrip()方法删除任何结尾的\ 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'作为rstrip的参数意味着它将删除任何'\ r'或'\ n'的尾部组合。 这就是为什么它在上述所有三种情况下都有效。

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

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

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

请注意,rstrip并不像Perl的chomp()那样动作,因为它不会修改string。 也就是说,在Perl中:

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

导致$x"a"

但在Python中:

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

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

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

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

我认为rstrip("\n")是,您可能需要确保行分隔符是可移植的。 (一些陈旧的系统被传言使用"\r\n" )。 另一个问题是, rstrip会删除重复的空白。 希望os.linesep将包含正确的字符。 上面的作品适合我。

你可以使用line = line.rstrip('\n') 。 这将从string的末尾剥离所有换行符,而不仅仅是一个。

 s = s.rstrip() 

将删除strings末尾的所有换行符。 因为rstrip返回一个新的string,而不是修改原始string,所以需要分配。

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

或者你可以总是得到正则expression式:)

玩的开心!

小心使用"foo".rstrip(os.linesep) :这样只会为您正在执行的Python平台换取换行符。 想象一下,您正在Linux下ch行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' >>> 

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

你可以使用strip:

 line = line.strip() 

演示:

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

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

Perl的chomp函数只有在实际存在的情况下才会从一个string的末尾删除一个换行序列。

这里是我打算如何在Python中做到这一点,如果process在概念上是我需要的function,以便从这个文件中的每一行做一些有用的事情:

 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) 

在这么多的层面上,rstrip和chomp不一样。 阅读http://perldoc.perl.org/functions/chomp.html ,看到chomp确实非常复杂。

不过,我的主要观点是,chomp最多可以删除1行结尾,而rstrip会删除尽可能多的行。

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

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

对于典型的Perl chomp用法可以用re.sub来完成,比如:

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

我没有用Python编程,但是我在python.org上发现了一个FAQ ,它提倡使用python 2.2或更高版本的S.rstrip(“\ r \ n”)。

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

特殊情况的解决方法:

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

 foobar= foobar[:-1] 

切出你的换行符。

如果你的问题是要清理多行str对象(oldstr)中的所有换行符,可以根据分隔符“\ n”将它拆分成一个列表,然后把这个列表join到一个新的str(newstr)中。

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

这将为“\ n”行结束符精确地复制perl的chomp(减去数组的行为):

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

(注意:它不会修改string'in place';它不会去掉多余的尾部空白;占用\ r \ n)

只要使用:

 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' 

我们通常会遇到三种types的结尾: \n\r\r\n 。 在re.sub一个相当简单的正则expression式,即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

抓住一切:

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

如果你关心速度(比如说你有一串串的string)并且你知道换行字符的性质,string切片实际上比rstrip更快。 一个小testing来说明这一点:

 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.92700004578 Method 2: 6.73000001907 

看起来像perl的chomp没有一个完美的模拟。 特别是, rstrip不能处理像\r\n这样的多字符换行符分隔符。 然而, 分裂线 在这里指出 。 根据我对不同问题的回答,你可以结合连接和拆分来删除/replacestrings所有换行符:

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

我发现能够通过迭代器获得经过简化的线条是非常方便的,与从文件对象获得未经过裁切的线条的方式并行。 你可以用下面的代码来做到这一点:

 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) 

我冒泡了一个我之前在另一个回答的评论中发表的基于正则expression式的答案。 我认为使用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' 

?:是创build一个非捕获组。

(顺便说一句,这不是什么'...'.rstrip('\n', '').rstrip('\r', '')可能并不清楚这个线程的其他绊脚石str.rstrip尽可能多的尾随字符,所以像foo\n\n\n这样的string会导致foo的误报,而您可能希望在str.rstrip尾随字符后保留其他换行符。)