末尾の改行を削除するにはどうすればよいですか?


1689

chomp改行である場合に文字列の最後の文字を削除するPerlの関数に相当するPythonの機能は何ですか?


2
スーパーセット:だけではなく、改行の任意の文字列:stackoverflow.com/questions/1038824/...
チロSantilli冠状病毒审查六四事件法轮功

3
A +の答えは、これがプラットフォームopen()の適切な「newline = ...」パラメーターを含むファイルを忘れたことが原因である場合(ユニバーサル改行サポート)、明示的に削除する必要がない場合があります。
smci

回答:


1868

メソッドを試すrstrip()(doc Python 2およびPython 3を参照)

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

Pythonのrstrip()メソッドは、Perlのように改行を1つだけではなく、デフォルトですべての種類の末尾の空白を削除します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'

22
私はPythonの人ではないので、これに対する答えはありませんが、Perlのchomp()は実際には入力レコードの区切り文字を末尾から削除します。これはUnix的なものでは改行ですが、異なる場合があり(Windowsなど)、変更可能です。文字列の終わりから一度だけその値を削除する方法はありますか?
brian d foy 2008年

5
brian d foy:Pythonには、awkやPerlのような入力レコードセパレータはありません。
Peter Hosey

7
@csde_rats、それは真実ではありません:OS Xは\nUnixと同じように改行を使用します。(OS X以前は、MacOS \rは行区切り文字として使用していましたが、10年前に終了しました。)
skue

21
@briandfoy Pythonには、ユニバーサル改行のサポートが組み込まれています(読み取り時のみで、書き込み時ではありません)。ファイルを「U」または「rU」モードで開き、Windows、Linux、Macなどに関係なく、テキストがpythonコードに到達するまでに、改行のスタイルはすべて「\ n」に置き換えられています。参照:python.org/dev/peps/pep-0278
AlcubierreDrive

12
私は初心者なので、なぜこれが機能しないのか疑問に思っていたので、先に進んでこれを詳しく説明します。.strip()文字列を変更しません(おそらく不変文字列と関係があります)。コマンドラインにない場合は、次のようにする必要があります"string = string.strip()"
Script Kitty


146

行末(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'

rstripのパラメーターとして「\ r \ n」を使用すると、「\ r」または「\ n」の末尾の組み合わせがすべて取り除かれます。それが上記の3つのケースすべてで機能する理由です。

このニュアンスはまれなケースで重要です。たとえば、HL7メッセージを含むテキストファイルを処理する必要がありました。HL7標準では、EOL文字として末尾の「\ r」が必要です。このメッセージを使用していたWindowsマシンには、独自の「\ r \ n」EOL文字が追加されていました。したがって、各行の終わりは「\ r \ r \ n」のようになりました。rstrip( '\ r \ n')を使用すると、 '\ r \ r \ n'全体が削除されますが、これは私が望んでいたものではありません。その場合、代わりに最後の2つの文字を切り捨てました。

Perlのchomp関数とは異なり、これは文字列の最後にある1つだけでなく、指定されたすべての文字を削除することに注意してください。

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

7
最新のMac OS Xアプリは\ nを使用することに注意してください。もともとMac OS用に作成された古いCarbonアプリのみが\ rを使用します。
Peter Hosey

2
説明をありがとう。もちろん、その場合もrstrip( '\ r \ n')は機能します。
マイク

13
os.linesep現在のOSのEOLシーケンスを含むもあります。
Eli Collins

これが最良の答えです。これは改行を取り除くだけであり、最も一般的なプラットフォームでは正しく行われます。
kevinarpe 2015

プラス+1 \nおよびand\r
fechnert 2015年

99

rstripは文字列を変更しないため、Perlのchomp()とまったく同じようには動作しません。つまり、Perlでは:

$x="a\n";

chomp $x

結果$xとして"a"ます。

しかしPythonでは:

x="a\n"

x.rstrip()

の値xまだ であることを意味します"a\n"x=x.rstrip()文字列の最後からすべての空白を取り除き、せいぜい1つの改行だけではないため、常に同じ結果が得られるとは限りません。


7
また、strip()は繰り返される文字を削除しますが、chop / chompは1つの改行のみを削除します
kostmo

50

私はこのようなものを使うかもしれません:

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

問題rstrip("\n")は、おそらく行区切り文字が移植可能であることを確認したいことだと思います。(一部の時代遅れのシステムはを使用すると噂されています"\r\n")。他の落とし穴は、rstrip繰り返される空白を取り除くことです。うまくいけばos.linesep、適切な文字が含まれます。上記は私のために働きます。


12
ただし、Webアプリケーションでユーザーが送信したコンテンツをクリーンアップしようとすると、これは機能しません。ユーザーコンテンツは任意のソースから取得でき、改行文字を含めることができます。
apiguy

2
最近のOSで(古くなったシステムからの)「外部」ファイルを処理している可能性があることを除いて、良い点です。
ChuckCottrill、2016

1
また、テキストモードでファイルを読み取っている場合、末尾の文字は常に「\ n」に変換されるため、これはWindowsシステムでも機能しません。
Mad Physicist

@MadPhysicistあなたはそれがそれを変換することは正しいですが、それは引数rstrip('\r\n')と同じrstrip()であり、引数にあるすべての文字を取り除くのでまだ機能します。
dtauxe

41

使用できますline = line.rstrip('\n')。これにより、1つだけでなく、文字列の末尾からすべての改行が削除されます。


35
s = s.rstrip()

文字列の最後にあるすべての改行を削除しますsrstrip元の文字列を変更する代わりに新しい文字列を返すため、割り当てが必要です。


33

これは、「\ n」行ターミネータのperlの問題(配列でのマイナスの動作)を正確に複製します。

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が考慮されます)


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

または、正規表現でいつでもマニアックになることができます:)

楽しんで!


これは、行末を含むテキストファイルを1行のテキストにすばやく変換しようとする場合に非常に役立ちました。私は初心者なので、もっと良い方法があるかどうかわかりませんが、うまくいきました、ありがとう!(ストリップは内部からではなく、端からのみ機能するように見えました)
Steve Koch

2
なぜ1つのreplaceステートメントを使用しないの.replace('\n|\r', '')ですか?
tckmn 2013

2
他の誰かが@DoorknobofSnowのアイデアを使用したい場合に備えて、正規表現モジュールimport re re.sub('\n|\r', '', '\nx\n\r\n')==> を使用することはほんの小さな変更'x'です。
テイラーエドミストン2014

@TaylorEdmistonが述べたように、これと正規表現手法を使用するのが適切な答えです。
Bhargav 2017

@Bhargav他のいくつかの関連オプションも検討しながら、あなたが提案したように、このコメントに基づいてこの質問への回答を追加しました。私はまた、なぜ正規表現がstr.rstripよりもこの問題のより良い解決策であると思うのかを明確にしました。
テイラーエドミストン2017

27

あなたはストリップを使うことができます:

line = line.strip()

デモ:

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

1
このソリューションを試しましたが、行の先頭の空白が取り除かれました。
Tarik

@Tarikはrstripを使用できます
Hackaholic

rstripは、せいぜい1つの改行しか削除しないchompとは異なり、末尾の空白をすべて削除します。
Flimm

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チョンプの使用法に非常に近づくことができます。

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

2
功績、この非常に重要な詳細を指摘したのはあなただけです。ただし、上記の誰かが述べたように、別のシステムからファイルを読み取っている場合は、os.linesepを使用しても機能しません。Pythonでこれを行うと、実際に行末を検査するのに少し時間がかかる場合があります。
brianmearns 2012

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")マイクは上記の言うように、代わりに。


もう1つの注意点は、とは異なり、多くても1つの改行ではなく、すべての改行が削除されることchompです。
Flimm 2016年

19

Pythonのドキュメント例では、単にを使用していline.strip()ます。

Perlのchomp関数は、実際にそこにある場合にのみ、文字列の最後から1つの改行シーケンスを削除します。

これが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)

2
最後に、(実際のむさぼりのように)一度しか削除せず、OS移植可能な回答
Ciro Santilli冠状病毒审查六四事件法轮功

13

私はPythonでプログラミングしていませんが、python.orgでpython 2.2以降のS.rstrip( "\ r \ n")を支持するFAQを見つけました。


10
import re

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

2
これにより、元の質問では要求されていないタブの空白も削除されます。(\ t文字が
原因

9

ファイルオブジェクトからチョップされていない行を取得する方法と並行して、イテレータでチョップされた行を取得できると便利です。これは次のコードで実行できます。

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)

注:operator.methodcallerand mapitertools.imapPy2の場合)を使用すると、この作業をCレイヤーにプッシュして、Pythonレベルジェネレーターコードを回避できます(そのため、I / Oオーバーヘッドが小さいゲインをマスクする可能性が高いですが、少し高速で実行されます)for line in map(operator.methodcaller('rstrip', '\r\n'), infile):。それはまだとして因数分解できますdef chomped_lines(it): return map(operator.methodcaller('rstrip', '\r\n'), it)
ShadowRanger 2017

8

特別な場合の回避策:

改行文字が最後の文字である場合(ほとんどのファイル入力の場合と同様)、コレクション内の任意の要素について、次のようにインデックスを作成できます。

foobar= foobar[:-1]

改行文字を切り取る。


3
時々、改行は最後の文字ではなく、特にウィンドウでは、他の人が指摘したように最後の文字です。
カコフスキー

8

質問が複数行strオブジェクト(oldstr)のすべての改行をクリーンアップする場合は、区切り文字 '\ n'に従ってリストに分割し、このリストを新しいstr(newstr)に結合できます。

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


7

perl's chompには完璧なアナログがないようです。特に、rstripはのような複数文字の改行区切り文字を処理できません\r\n。ただし、splitlinesここで指摘されているように機能します。別の質問に対する私の回答に続き結合分割線を組み合わせて、文字列からすべての改行を削除/置換できますs

''.join(s.splitlines())

次の例では、末尾の改行を1つだけ削除します(私が信じているように)。分割線へTruekeepends引数として渡しても、区切り文字は保持されます。次に、splitlinesが再び呼び出され、最後の「行」の区切り文字が削除されます。

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

7

私は以前に別の回答のコメントで投稿したものからの私の正規表現ベースの回答を泡立たせています。を使用することreは、この問題の明確な解決策であると考えていstr.rstripます。

>>> import re

1つ以上の末尾の改行文字を削除する場合:

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

私はほとんどの人は本当にここに何をしたい気持ちを持って、単に削除しないことである1改行文字の発生を、いずれか\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あなたが保存したかったかもしれないのに対し、末尾の1行を削除した後の他の改行。)


最終的なアプローチであっても、正規表現を使用して非キャプチャグループをスキップできますr'\r?\n$'。正規表現エンジンは代替を最適化するのに苦労するため、おそらくより効率的です。また、これを何度も実行する場合は、最初に式をre使用すると(特に他の用途と混ざっている場合)re.compile、式が大幅に速くなりsub、コンパイルされた正規表現オブジェクトのメソッドを使用することに注意してください。モジュール関数はPythonレベルであり、まずコンパイルされた正規表現のキャッシュをチェックし(見つからない場合は作成/キャッシュ)、次に一致するメソッドを呼び出します。そのルックアップをスキップすると役立ちます。
ShadowRanger 2017

1
また、補足:\n直接一致させようとしているので、\Zover を使用することもできます$(または、文字列の末尾の改行の直前で暗黙的に一致できる\r?$ため、単にmatch を使用し$ます)。
ShadowRanger 2017

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

必要な例!したがって、rstrip( "\ r \ n")は '\ n'と '\ r'の両方を任意の組み合わせで行末で削除します!
Agostino

提供する@Agostinoありません必要"\r\n"例:' spacious \n\r\n\r \n\n'.rstrip()生産' spacious'
olibre

2
@olibre提案するコードは、他の空白/スペース文字も取り除きますが、これは必要としない場合があります。実際、私はeolキャラクターの組み合わせを取り除くだけで済みました。それでも、これを指摘してくれてありがとう。
Agostino

4

ただ使用する:

line = line.rstrip("\n")

または

line = line.strip("\n")

この複雑なものは必要ありません


2
これはchompと同じではないことに注意してください。
Flimm

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

3

そこ私たちは正常に遭遇すること行末の3種類があります\n\r\r\nre.subつまりr"\r?\n?$"、のかなり単純な正規表現は、それらすべてをキャッチできます。

(そして、私たちはすべてを捕まえなければならない、私は正しいのですか?)

import re

re.sub(r"\r?\n?$", "", the_text, 1)

最後の議論では、置き換えられる出現の数を1つに制限し、むち打ちをある程度模倣します。例:

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


本格的な正規表現も必要ありません。rstrip("\r\n")キャッチオールです。お試しくださいprint(text_2.rstrip('\r\n'))
Agostino

@Agostino:str.rstrip()問題が解決すれば、そうだ。それはあなたが持っているニーズに依存します。このソリューションは、最後のだけを削除する必要がある場合"\n""\r"または"\r\n"すべてを削除する必要がない場合("\n"文字列に複数ある場合)に対して特別に作成されます。re.sub(r"\r?\n?$", "", text_1, 1)リターン"hellothere\n\n"text_1.rstrip("\r\n")リターン"hellothere"異なる文字列です。
インターネットで

私が言おうとしていることstr.strip()は、それがキャッチオールであることが時々非常に問題です。
インターネットで

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

関数内で「グローバルループ」を使用する必要があることはわかっていますが、これも機能します。
Stephen Miller

このテストは誤りであり、公平ではありません。最初のチェックで、文字列の末尾に不要な文字が含まれていて、それらが切り落とさmethod1method2ているかどうかに関係なく、最後の文字を切り落としているだけです.rstrip()。の文字のチェックを実装してmethod1、アギンをテストしてください!
2016年

回答の紹介で述べたように、改行文字の性質を知っている場合は、これが役立ちます。そうしないと、明らかに、ある種の文字チェックを実装する必要があります-または単にrstripを使用します。私はrstripに対して「不公平」であるという意味ではなく、状況によっては検討する価値のある、それほど重要ではない違いを単に示しています。
Stephen Miller

1

これは、windowsとlinuxの両方で機能します(reソリューションのみを探している場合、re subを使用するとビットが高くなります)。

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


3
なぜre.search必要な場所で使用するのre.subですか?
wjandrea

0

最初にラインを分割してから、好きなセパレータでそれらを結合します:

x = ' '.join(x.splitlines())

魅力のように動作するはずです。


-1

すべてをキャッチ:

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

5
rstrip正規表現を取りません。"hi|||\n\n".rstrip("\r|\n")リターン"hi"
Flimm
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.