1909

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

4

27 回答 27

2146

尝试该方法rstrip()(请参阅文档Python 2Python 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 '

除此之外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'
于 2008-11-08T18:31:53.113 回答
180

我会说在没有尾随换行符的情况下获取行的“pythonic”方法是 splitlines()。

>>> text = "line 1\nline 2\r\nline 3\nline 4"
>>> text.splitlines()
['line 1', 'line 2', 'line 3', 'line 4']
于 2008-11-09T05:52:43.990 回答
163

去除行尾 (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 标准要求尾随 '\r' 作为其 EOL 字符。我使用此消息的 Windows 机器附加了它自己的 '\r\n' EOL 字符。因此,每一行的结尾看起来像 '\r\r\n'。使用 rstrip('\r\n') 会删除整个 '\r\r\n' 这不是我想要的。在这种情况下,我只是简单地切掉了最后两个字符。

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

>>> "Hello\n\n\n".rstrip("\n")
"Hello"
于 2008-11-09T00:11:21.447 回答
102

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

$x="a\n";

chomp $x

结果$x"a"

但在 Python 中:

x="a\n"

x.rstrip()

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

于 2008-11-28T17:31:34.567 回答
51

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

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

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

于 2010-03-07T16:07:27.817 回答
41

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

于 2013-05-13T16:41:22.337 回答
37
s = s.rstrip()

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

于 2015-03-09T08:02:55.947 回答
34
"line 1\nline 2\r\n...".replace('\n', '').replace('\r', '')
>>> 'line 1line 2...'

或者你总是可以用正则表达式变得更怪异

于 2012-02-29T22:40:11.213 回答
34

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

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)

于 2015-10-01T08:33:32.383 回答
28

你可以使用条带:

line = line.strip()

演示:

>>> "\n\n hello world \n\n".strip()
'hello world'
于 2014-11-21T04:29:07.607 回答
20

在很多层面上,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'
于 2011-04-23T12:42:25.337 回答
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)
于 2013-10-23T01:32:11.793 回答
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'
>>>

"foo".rstrip("\r\n")如迈克上面所说,请改用。

于 2011-04-27T11:43:20.157 回答
13

我没有使用 Python 编程,但我在 python.org 上遇到了一个常见问题解答,提倡 S.rstrip("\r\n") 用于 python 2.2 或更高版本。

于 2009-07-03T01:49:19.590 回答
12
import re

r_unwanted = re.compile("[\n\t\r]")
r_unwanted.sub("", your_text)
于 2014-01-20T19:07:03.187 回答
9

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

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

于 2013-10-11T11:56:21.093 回答
9

我发现能够通过 in 迭代器获取 chomped 行很方便,这与从文件对象获取 unchomped 行的方式平行。您可以使用以下代码执行此操作:

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)
于 2015-01-11T18:47:33.673 回答
9

我正在从我之前在另一个答案的评论中发布的一个基于正则表达式的答案中冒泡。我认为 usingre是比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而您可能希望保留剥离单个尾随换行符后的其他换行符。)

于 2017-07-27T05:24:28.030 回答
8

特殊情况的解决方案:

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

foobar= foobar[:-1]

切出你的换行符。

于 2011-11-30T14:04:19.880 回答
7
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'

使用正则表达式

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 '

使用正则表达式

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'
于 2019-10-22T07:43:27.193 回答
7

看起来 perl 的chomp没有完美的模拟。特别是,rstrip无法处理多字符换行符,如\r\n. 但是,splitlines确实如此处指出的那样。按照对另一个问题的回答,您可以结合joinsplitlines来删除/替换字符串中的所有换行符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 ''
于 2017-04-26T17:58:16.047 回答
5
>>> '   spacious   '.rstrip()
'   spacious'
>>> "AABAA".rstrip("A")
  'AAB'
>>> "ABBA".rstrip("AB") # both AB and BA are stripped
   ''
>>> "ABCABBA".rstrip("AB")
   'ABC'
于 2016-11-22T18:30:37.740 回答
4

只需使用:

line = line.rstrip("\n")

或者

line = line.strip("\n")

你不需要任何这些复杂的东西

于 2016-05-20T12:29:21.160 回答
3

我们通常会遇到三种类型的行尾\n\r\r\n。中的一个相当简单的正则表达式re.sub,即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 == c哪里True

于 2016-11-22T20:17:58.357 回答
1

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

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
于 2015-10-28T13:56:42.960 回答
0

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

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

于 2018-06-15T07:24:21.817 回答
-3

包罗万象:

line = line.rstrip('\r|\n')
于 2014-10-24T18:34:12.660 回答