How can I remove a trailing newline in Python?
Perl的
尝试方法
1 2 3 | >>> 'test string '.rstrip() 'test string' |
python的
1 2 3 4 5 6 7 8 9 | >>> 'test string '.rstrip() 'test string' |
只删除换行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | >>> 'test string '.rstrip(' ') 'test string ' |
还有方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | >>> s =" abc def " >>> s.strip() 'abc def' >>> s.lstrip() 'abc def ' >>> s.rstrip() ' abc def' |
我要说的是"pythonic"方法,在不拖尾换行符的情况下获取行是splitlines()。
1 2 3 4 5 6 7 | >>> text ="line 1 line 2 line 3 line 4" >>> text.splitlines() ['line 1', 'line 2', 'line 3', 'line 4'] |
去除行尾(eol)字符的标准方法是使用字符串r strip()方法删除任何尾随的
或字符。以下是Mac、Windows和Unix eol字符的示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | >>> 'Mac EOL '.rstrip(' ') 'Mac EOL' >>> 'Windows EOL '.rstrip(' ') 'Windows EOL' >>> 'Unix EOL '.rstrip(' ') 'Unix EOL' |
使用'
'作为r strip的参数意味着它将除去'
'或''的任何尾随组合。这就是为什么它适用于上述三种情况。
这种细微差别在罕见的情况下很重要。例如,我曾经必须处理一个包含HL7消息的文本文件。HL7标准要求尾随的'
'作为其EOL字符。我使用此消息的Windows计算机已附加了自己的
"eol字符。因此,每行的结尾看起来像'
'。使用rstrip("
")可以去掉整个'
',这不是我想要的。在这种情况下,我只是简单地切掉最后两个字符。
注意,与Perl的
1 2 3 4 5 6 | >>>"Hello ".rstrip(" ") "Hello" |
请注意,rstrip的行为并不完全像perl的chomp(),因为它不会修改字符串。也就是说,在Perl中:
1 2 3 4 | $x="a "; chomp $x |
结果
但在Python:
1 2 3 4 | x="a " x.rstrip() |
也就是说,
"
我可能会用这样的东西:
1 2 | import os s = s.rstrip(os.linesep) |
我认为
")
"。另一个问题是,
您可以使用
')
1 | s = s.rstrip() |
将删除字符串
这将为"行终止符复制Perl的chomp(减去数组上的行为):
1 2 3 4 5 6 7 8 | def chomp(x): if x.endswith(" "): return x[:-2] if x.endswith(" ") or x.endswith(" "): return x[:-1] return x |
(注意:它不修改字符串'in-place';它不删除多余的尾随空格;考虑
)
1 2 3 4 5 6 7 | "line 1 line 2 ...".replace(' ', '').replace(' ', '') >>> 'line 1line 2...' |
或者你总是能在regexps上变得更有趣:)
玩得高兴!
您可以使用条带:
1 | line = line.strip() |
演示:
1 2 3 4 5 6 | >>>" hello world ".strip() 'hello world' |
小心使用
1 2 3 4 5 6 7 8 9 10 11 12 13 | $ 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 ".rstrip(os.linesep) 'foo ' >>> |
用
")代替,正如迈克上面所说的。
python文档中的一个示例只使用
Perl的
下面是我计划在python中实现这一点的方法,如果
1 2 3 4 5 6 7 | 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删除了所有新行:
1 2 3 4 | >>> 'foo '.rstrip(os.linesep) 'foo' |
使用re.sub可以更接近典型的Perl Chomp用法,如下所示:
1 2 3 4 5 | >>> re.sub(os.linesep + r'\Z','','foo ') 'foo ' |
我没有用python编程,但我在python.org上遇到了一个常见问题解答,它提倡S.rstrip("
")用于python 2.2或更高版本。
1 2 3 4 5 6 | import re r_unwanted = re.compile("[ \t ]") r_unwanted.sub("", your_text) |
针对特殊情况的解决方案:
如果换行符是最后一个字符(大多数文件输入都是这样),那么对于集合中的任何元素,可以按如下方式进行索引:
1 | foobar= foobar[:-1] |
把你的换行符切掉。
如果您的问题是清除多行str对象(oldstr)中的所有换行符,则可以根据分隔符'将其拆分为一个列表,然后将此列表加入到新的str(new str)。
'))
我发现能够通过迭代器获取被选中的行很方便,这与从文件对象获取未被选中的行的方式是平行的。您可以使用以下代码执行此操作:
1 2 3 4 | def chomped_lines(it): return map(operator.methodcaller('rstrip', ' '), it) |
样品使用情况:
1 2 3 | with open("file.txt") as infile: for line in chomped_lines(infile): process(line) |
似乎没有一个完美的Perl Chomp模拟。特别是,rstrip不能处理多字符换行符,如
。然而,分割线就像这里指出的那样。根据我对另一个问题的回答,您可以将连接线和拆分线组合在一起,以从字符串
1 | ''.join(s.splitlines()) |
下面只删除了一条尾随的换行符(我相信Chomp会这样做)。将
1 2 3 4 5 6 7 | def chomp(s): if len(s): lines = s.splitlines(True) last = lines.pop() return ''.join(lines + last.splitlines()) else: return '' |
我正在从先前在另一个答案的评论中发布的基于正则表达式的答案中冒泡出来。我认为使用
1 | >>> import re |
如果要删除一个或多个尾随换行符:
1 2 3 4 5 6 7 8 | >>> re.sub(r'[ ]+$', '', ' x ') ' x' |
如果要在所有位置删除换行符(不仅仅是尾随字符):
1 2 3 4 5 6 7 | >>> re.sub(r'[ ]+', '', ' x ') 'x' |
如果只想删除1-2个尾随换行符字符(即
、
、
、
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | >>> re.sub(r'[ ]{1,2}$', '', ' x ') ' x ' >>> re.sub(r'[ ]{1,2}$', '', ' x ') ' x ' >>> re.sub(r'[ ]{1,2}$', '', ' x ') ' x' |
我有一种感觉,在这里大多数人真正想要的是去掉一个尾随的换行符,要么是
,要么是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | >>> re.sub(r'(?: | )$', '', ' x ', count=1) ' x ' >>> re.sub(r'(?: | )$', '', ' x ', count=1) ' x ' >>> re.sub(r'(?: | )$', '', ' x ', count=1) ' x' >>> re.sub(r'(?: | )$', '', ' x ', count=1) ' x' |
(
(顺便说一句,这不是
', '').rstrip('
', '')
这样的字符串将导致
只需使用:
1 2 | line = line.rstrip(" ") |
或
1 2 | line = line.strip(" ") |
你不需要这些复杂的东西
1 2 3 4 5 6 7 8 | >>> ' spacious '.rstrip() ' spacious' >>>"AABAA".rstrip("A") 'AAB' >>>"ABBA".rstrip("AB") # both AB and BA are stripped '' >>>"ABCABBA".rstrip("AB") 'ABC' |
我们通常会遇到三种类型的行尾:
。在
?
?$"
(我们要抓住他们,对吗?)
1 2 3 4 5 | import re re.sub(r" ? ?$","", the_text, 1) |
最后一个论点是,我们将替换的发生次数限制为一次,在某种程度上模仿chomp。例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | import re text_1 ="hellothere " text_2 ="hellothere " text_3 ="hellothere " a = re.sub(r" ? ?$","", text_1, 1) b = re.sub(r" ? ?$","", text_2, 1) c = re.sub(r" ? ?$","", text_3, 1) |
…其中
如果你关心速度(比如你有一个很长的字符串列表),并且你知道换行符的性质,那么字符串切片实际上比rstrip快。一个小测试来说明这一点:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import time loops = 50000000 def method1(loops=loops): test_string = 'num ' 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 ' t0 = time.time() for num in xrange(loops): out_sting = test_string.rstrip() t1 = time.time() print('Method 2: ' + str(t1 - t0)) method1() method2() |
输出:
1 2 | Method 1: 3.92700004578 Method 2: 6.73000001907 |
这对Windows和Linux都适用(如果您只想寻找RE解决方案,那么Re-Sub有点贵)
1 2 3 4 5 6 7 | import re if re.search("(\ |)\ $", line): line = re.sub("(\ |)\ $","", line) |
一举一动:
1 2 3 | line = line.rstrip(' | ') |