Как удалить (chomp) завершающую новую строку в Python?

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

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

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

rstrip() 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) – использовать метод 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 требует, чтобы в качестве символа EOL использовался конечный «\ r». Машина Windows, на которой я использовала это сообщение, добавила свой собственный символ «\ r \ n» EOL. Поэтому конец каждой строки выглядел как «\ r \ r \ n». Использование rstrip (‘\ r \ n’) удалило бы все «\ r \ r \ n», чего я не хотел. В этом случае я просто нарезал последние два символа.

Обратите внимание, что в отличие от функции chomp Perl, это приведет к удалению всех указанных символов в конце строки, а не только к одному:

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

Обратите внимание, что rstrip не действует точно так же, как chomp () Perl, потому что он не изменяет строку. То есть, в 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 возвращает новую строку вместо изменения исходной строки.

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

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

повеселись!

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

 line = line.strip() 

демо:

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

Осторожно с помощью "foo".rstrip(os.linesep) : Это будет только chomp символы новой строки для платформы, на которой выполняется ваш 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") используйте "foo".rstrip("\r\n") , как говорит Майк выше.

Пример в документации Python просто использует line.strip() .

Функция chomp Perl удаляет одну последовательность строк из конца строки только в том случае, если она на самом деле существует.

Вот как я планирую сделать это в 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) 

Это позволит точно воспроизвести 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 

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

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, защищающим S.rstrip («\ r \ n») для python 2.2 или новее.

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

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

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

 foobar= foobar[:-1] 

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

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

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

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

 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) 

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

 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' 

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

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

Я поднимаю свой ответ на основе регулярных выражений от одного, который я опубликовал ранее в комментариях к другому ответу. Я думаю, что использование 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', '') , что может быть непонятным для других, преследующих этот stream str.rstrip как можно больше символов завершающего символа, поэтому строка, подобная foo\n\n\n приведет к ложному положительному результату foo тогда как вы, возможно, захотите сохранить другие символы новой строки после удаления одного завершающего символа.)

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

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

Уловим все:

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

Это будет работать как для windows, так и для linux (бит дорогостоящий с повторным подключением, если вы ищете только новое решение)

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

Interesting Posts

Windows XP PRO SP3 – остановить изменения ключа ключа безопасности, установленного неизвестной программой

Поддержка Windows 7 x64 для Intel GMA 3650 (или GMA 3600)

Диалоговое окно JQuery UI не размещено на центральном экране

UIImageWriteToSavedPhotosAlbum сохраняет неправильный размер и качество

Как изменить регион моего маршрутизатора?

Приложение, использующее профиль bluetooth SPP, не работает после обновления с Android 4.2 до Android 4.3

Могу ли я передать загрузку файла на S3 без заголовка содержимого?

В чем разница между кибибатом, килобитом и килобайтом?

Windows 7 Aero тема "greyed out" – не найдено исправления

как преобразовать цвет rgb в int в java

Отправить SMS с помощью намерения

Как создать приложение на C #, которое решит, показывать ли его как консольное или оконное приложение?

В чем разница между дисплеем: встроенным и отображаемым: встроенный блок?

Как смонтировать раздел EFI в Windows 8.1, чтобы он был доступен для чтения и записи?

Java ArrayList – как я могу определить, равны ли два списка, порядок не имеет значения?

Давайте будем гением компьютера.