什么是Perl chomp
函数的Python等价物,如果它是换行符,它会删除字符串的最后一个字符?
尝试该方法rstrip()
(参见文档Python 2和Python 3)
>>> 'test string\n'.rstrip() 'test string'
Python的rstrip()
方法默认情况下会删除所有类型的尾随空格,而不仅仅是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)字符的规范方法是使用字符串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'
使用'\ 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"
请注意,rstrip的行为与Perl的chomp()完全不同,因为它不会修改字符串.也就是说,在Perl中:
$x="a\n"; chomp $x
导致$x
存在"a"
.
但在Python中:
x="a\n" x.rstrip()
将意味着价值x
是依旧 "a\n"
.甚至x=x.rstrip()
并不总是给出相同的结果,因为它从字符串的末尾剥离所有空格,而不是最多只有一个换行符.
我可能会使用这样的东西:
import os s = s.rstrip(os.linesep)
我认为问题rstrip("\n")
在于您可能希望确保行分隔符是可移植的.(据传有些过时的系统使用"\r\n"
).另一个问题是rstrip
将删除重复的空格.希望os.linesep
包含正确的字符.以上对我有用.
你可以用line = line.rstrip('\n')
.这将从字符串的末尾删除所有换行符,而不仅仅是一行.
s = s.rstrip()
将删除字符串末尾的所有换行符s
.需要赋值,因为rstrip
返回一个新字符串而不是修改原始字符串.
这将为"\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
(注意:它不会修改字符串'in place';它不会删除额外的尾随空格;在帐户中取\ r \n)
你可以使用strip:
line = line.strip()
演示:
>>> "\n\n hello world \n\n".strip() 'hello world'
"line 1\nline 2\r\n...".replace('\n', '').replace('\r', '') >>> 'line 1line 2...'
或者你可以随时使用regexps :)
玩得开心!
小心"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' >>>
使用"foo".rstrip("\r\n")
替代,如麦克上述表示.
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)
在很多层面上,rstrip与chomp不同.阅读http://perldoc.perl.org/functions/chomp.html,看看chomp确实非常复杂.
但是,我的主要观点是chomp最多删除1行结束,而rstrip将删除尽可能多的行.
在这里你可以看到删除所有新行的rstrip:
>>> 'foo\n\n'.rstrip(os.linesep) 'foo'
使用re.sub可以更加接近典型的Perl chomp用法,如下所示:
>>> re.sub(os.linesep + r'\Z','','foo\n\n') 'foo\n'
我不用Python编程,但是我在python.org上遇到了一个常见问题解答,主张用于python 2.2或更高版本的S.rstrip("\ r \n").
import re r_unwanted = re.compile("[\n\t\r]") r_unwanted.sub("", your_text)
如果您的问题是清除多行str对象(oldstr)中的所有换行符,则可以根据分隔符'\n'将其拆分为列表,然后将此列表连接到新的str(newstr).
newstr = "".join(oldstr.split('\n'))
我发现能够通过迭代器获取chomped行很方便,与从文件对象中获取未选择行的方式并行.您可以使用以下代码执行此操作:
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)
解决特殊情况的解决方案:
如果换行符是最后一个字符(与大多数文件输入的情况一样),那么对于集合中的任何元素,您可以索引如下:
foobar= foobar[:-1]
切出你的换行符.
看起来perl的chomp没有完美的模拟.特别是,rstrip无法处理多字符换行分隔符\r\n
.然而,splitlines不会因为在这里指出.根据我对其他问题的回答,您可以组合连接和拆分线以从字符串中删除/替换所有换行符s
:
''.join(s.splitlines())
以下删除了一个尾随换行符(我相信chomp会这样).True
作为keepends
分裂线的参数传递保留分隔符.然后,再次调用splitlines以删除最后一行"分隔符":
def chomp(s): if len(s): lines = s.splitlines(True) last = lines.pop() return ''.join(lines + last.splitlines()) else: return ''
我正在鼓励我从前面在另一个答案的评论中发布的一个基于正则表达式的答案.我认为使用re
是比这个问题更清晰,更明确的解决方案str.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
,而你可能想保留剥离单个尾随后的其他换行符.)