it-swarm.com.ru

Как я могу удалить завершающий перевод строки в Python?

Что является Python-эквивалентом функции Perl chomp, которая удаляет последний символ строки, если она является новой строкой?

1430
RidingThisToTheTop

Попробуйте метод rstrip() (см. Doc Python 2 и Python 3 )

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

Метод Python rstrip() по умолчанию удаляет all конечные пробелы, а не только одну новую строку, как это делает 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'
1524
Rich Bradshaw

И я бы сказал, что "Pythonic" способ получить строки без завершающих символов новой строки - это splitlines ().

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

Канонический способ удаления символов конца строки (EOL) заключается в использовании метода string 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"
134
Mike

Обратите внимание, что rstrip не действует точно так же, как Perl chomp (), потому что он не изменяет строку. То есть в Perl:

$x="a\n";

chomp $x

в результате $x будет "a".

но в Python:

x="a\n"

x.rstrip()

будет означать, что значение x равно все еще "a\n". Даже функция x=x.rstrip() не всегда дает один и тот же результат, поскольку она удаляет все пробелы в конце строки, а не только одну новую строку.

98
Sameer Siruguri

Я мог бы использовать что-то вроде этого:

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

Я думаю, что проблема с rstrip("\n") заключается в том, что вы, вероятно, захотите убедиться, что разделитель строк является переносимым. (по некоторым слухам, некоторые устаревшие системы используют "\r\n"). Другая проблема заключается в том, что rstrip удалит повторяющиеся пробелы. Надеюсь, os.linesep будет содержать правильные символы. вышеупомянутое работает для меня.

47
Jamie

Вы можете использовать line = line.rstrip('\n'). Это удалит все новые строки с конца строки, а не только один.

39
octoback
s = s.rstrip()

удалит все символы новой строки в конце строки s. Назначение необходимо, потому что rstrip возвращает новую строку вместо изменения исходной строки. 

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

или вы всегда можете получить geekier с регулярными выражениями :)

повеселись!

25
mihaicc

Это будет точно повторять chomp Perl (минус поведение в массивах) для терминатора строки "\ 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

(Примечание: он не изменяет строку «на месте»; он не удаляет лишние конечные пробелы; учитывает\r\n)

23
Alien Life Form

вы можете использовать полосу:

line = line.strip()

демо:

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

Осторожно с "foo".rstrip(os.linesep): Это только скомпрометирует символы новой строки для платформы, на которой выполняется ваш Python. Представьте, что вы изменяете строки файла Windows под Linux, например:

$ 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"), как сказал Майк выше.

20
Carlos Valiente

пример в документации 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)
19
minopret

rstrip не делает то же самое, что chomp, на многих уровнях. Прочитайте http://perldoc.Perl.org/functions/chomp.html и убедитесь, что chomp действительно очень сложен.

Тем не менее, моя главная мысль заключается в том, что chomp удаляет не более 1 конца строки, тогда как rstrip удаляет столько, сколько может.

Здесь вы можете увидеть, как rstrip удаляет все новые строки:

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

С помощью re.sub может быть получено более близкое приближение типичного использования Chomp для Perl, например:

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

Я не программирую на Python, но я наткнулся на FAQ на python.org, защищающем S.rstrip ("\ r\n") для Python 2.2 или более поздней версии.

14
Andrew Grimm
import re

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

Если ваш вопрос состоит в том, чтобы очистить все разрывы строк в многострочном объекте str (oldstr), вы можете разбить его на список в соответствии с разделителем '\ n', а затем объединить этот список в новый str (newstr).

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

8
Leozj

обходное решение для особого случая:

если символ новой строки является последним символом (как в случае с большинством файловых входов), то для любого элемента в коллекции вы можете индексировать следующим образом: 

foobar= foobar[:-1]

вырезать ваш символ новой строки. 

8
Chij

Похоже, что не существует идеального аналога для Perl chomp . В частности, rstrip не может обрабатывать многосимвольные разделители новой строки, такие как \r\n. Тем не менее, splitlines do как указано здесь . Следуя моему ответу по другому вопросу, вы можете объединить join и splitlines , чтобы удалить/заменить все новые строки из строки s:

''.join(s.splitlines())

Следующее удаляет ровно один завершающий символ новой строки (как я полагаю, chomp). Передача True в качестве аргумента keepends для разделенных линий сохраняет разделители. Затем снова вызывается splitline, чтобы удалить разделители только на последней «строке»: 

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

Я нахожу удобным иметь возможность получать строки с шипами в итераторе параллельно с тем, как можно получать линии с шипами из файлового объекта. Вы можете сделать это с помощью следующего кода:

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)
6
kuzzooroo

Я запутываю свой ответ на основе регулярных выражений от ответа, который я разместил ранее в комментариях к другому ответу. Я думаю, что использование re является более четким и ясным решением этой проблемы, чем str.rstrip.

>>> import re

Если вы хотите удалить один или несколько символов трейлинг newline:

>>> 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 тогда как вы, возможно, хотели сохранить другие новые строки после удаления одного завершающего.)

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

Просто используйте: 

line = line.rstrip("\n")

или же

line = line.strip("\n")

Вам не нужно ничего из этого сложного материала

4
Help me

Есть три типа концов строк, с которыми мы обычно сталкиваемся: \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.

3
internetional

Если вас беспокоит скорость (скажем, у вас есть длинный список строк), и вы знаете природу символа новой строки, срезание строк на самом деле быстрее, чем 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
1
Stephen Miller

Это будет работать как для Windows, так и для Linux (немного дороже с re sub, если вы ищете только новое решение)

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

0
Venfah Nazir