Python で文字列の末尾の改行を削除する


急ぐ人向け

str_line.rstrip('\r\n') を使いましょう。

line_content = string_line.rstrip('\r\n')

(注: Perl の chomp と異なり、元の文字列を保持する非破壊操作です。)

以下、この記事を書いた理由(愚痴)

誰もが通ると思われる道だが、きっかけは「文字列を splitlines してから iterate するの、効率悪いんじゃね?」って思ったこと。

for line in string_content.splitlines():
    print(line)

google って調べて、
stack overflow の質問と回答にたどり着いた。

そこの回答を見て、「改行が \r\n の場合に対応するにはどうしたらいいか」

で Bing で「python chomp」で検索し、「rstrip() 使うといい」という Blog記事を見つけ、そのまま実装してしまった。

    # 注:問題ありコード
    def bad_line_iter(string_content):
        stri = io.StringIO(string_content)
        while True:
            nl = stri.readline()
            if nl != '':
                yield nl.rstrip()
            else:
                return

プログラム組み込み終わってテストする。
いくつか試していて想定外の動きをするものがあった。
デバッグ出力入れて調べたらiterator が空白のみの行を空文字列にしていた。

コードを見返す。・・・ rstrip って、名前からして右空白削除の関数やん。
調べたら実際にそうだった。で、末尾の連続する特定の文字群を削除する場合には rstip に引数に与えればよい。

そういうわけで修正。

    def line_iter(string_content):
        stri = io.StringIO(string_content)
        while True:
            nl = stri.readline()
            if nl != '':
                yield nl.rstrip(\r\n)
            else:
                return

で、改めて「python chomp」や「python 改行削除」で検索したのだが、
rstrip(’\r\n’) を挙げているものを(少なくとも上位では)見つけられなかった。(2021年8月15日現在)

そういうわけで、記事にしました。

なお、途中にでてきた Perl の chomp は破壊的関数(元も文字列を書きかえる)だが、Python の rstip は非破壊関数(元の文字列が保持される)点には注意。

>>> l = 'aaa \r\n'
>>> l
'aaa \r\n'
>>> print(l)
aaa 

>>> l.rstrip()
'aaa'
>>> l
'aaa \r\n'
>>> l.rstrip('\r\n')
'aaa '
>>> l.rstrip('\n')
'aaa \r'
>>> print(l.rstrip('\n'))
aaa 

>>> print(l.rstrip('\r\n'))
aaa