睡眠とパソコン

だいたい毎日更新するのでだいたい毎日来てください

Windowsの改行コードは\r\nなので\nの置換では改行を削除できない

要約

Unix系OSの改行コードは\nだけど、Windowsは\r\nなので、改行を削除するために\nを削除すると、想定外の動きをする。


経緯

何度もコピペする作業が必要となったため、クリップボードを監視して別ファイルに自動的に書き込むプログラムを作成した。

しかし、Windowsの改行コードが\r\nである事をすっかり忘れており、\nを消すことで対応しようとした。

環境

  • Windows 10 21H2 19044.2486
  • Python 3.9.5

Windowsの改行コードを\nだと思ったせいで起こった想定外の動作

text = "あいうえお\r\nかきくけこ\r\nさしすせそ"
print(text.replace("\n", "")) #=> さしすせそ

僕としては、改行が取り除かれて「あいうえおかきくけこさしすせそ」と出力されて欲しかったが、どういう訳か、上記のように最後の「さしすせそ」だけが出力された。

text = "あいうえお\r\nかきくけこ\r\nさしすせそ"
print(repr(text.replace("\n", ""))) # 'あいうえお\rかきくけこ\rさしすせそ'

文字列をraw文字列に変換するrepr()を使うと理由は明白で、以下の処理が行われていたらしい。

  1. 「あいうえお」と出力
  2. \rでカーソルが行頭に戻る
  3. 「かきくけこ」と出力(最初の「あいうえお」は上書きされる)
  4. カーソルが行頭に戻る
  5. 「さしすせそ」と出力(「かきくけこ」は上書きされる)

よって、標準出力に残るのは最後の「さしすせそ」だけだった、という顛末。

解決策

text = "あいうえお\r\nかきくけこ\r\nさしすせそ"
print(text.replace("\r\n", "")) # あいうえおかきくけこさしすせそ

Windowsでは\nではなく\r\nを置換することで改行を削除しよう。