テキストファイルで使われる改行コード(改行文字)にはLF(ラインフィード)、CR(キャリッジリターン)、CRLF(CRの後にLFが続く)の3つがあります。
どの改行コードが標準的に使われるかOSによって異なるため、間違った改行コードでテキストファイルを作成すると問題が発生する恐れがあります。
例えば改行コードがLFのテキストファイルを期待するプログラムがあるとします。このプログラムが改行コードにCRLFを使うテキストファイルを読み込むと、CR文字までを1行のテキストと解釈して正しく動作しないかもしれません。
このような間違いをチェックするときなど、テキストファイルの改行コードの判別が必要になる場合があります。この記事ではPythonで改行コードを判別する方法を解説します。
改行コードのエスケープシーケンス
最初にPythonで改行コードに使うエスケープシーケンスをおさらいしておきましょう。
Pythonに限らず多くのプログラミング言語で改行コードのような特殊な制御文字を扱う場合にはエスケープシーケンスを使います。Pythonでそれぞれの改行コードのエスケープシーケンスは次の通りです。
改行コード | エスケープシーケンス |
---|---|
LF | \n |
CR | \r |
CRLF | \r\n |
例えば「\n」という2文字はLFという1文字の制御文字を表します。エスケープシーケンスは文字を表すので文字列の中で利用します。
ファイルの改行コードを変換しないで読み込む
Pythonでテキストファイルを開くにはopen()関数を使います。
fin = open('sample.txt')
これはsample.txtファイルをオープンします。しかし、このようにテキストファイルをオープンすると改行コードを判別できません。
open()関数にはnewline引数がありますが、省略するとすべての改行コードは「\n」に変換されてしまい、ファイルの改行コードが何であったかわからなくなってしまうからです。つまりLF、CR、CRLFのいずれの改行コードを使ったテキストファイルでも、Pythonでファイルを読み込んだ後は「LF(\n)」になっています。
自動的に改行コードを変換しないようにするにはnewline引数に空文字列を指定します。
fin = open('sample.txt', newline='')
これでread()関数やreadline()関数などでファイルを読み込んだときに改行コードは変換されず、ファイルの改行コードがそのまま返されます。
Pythonでの改行コードの読み込み時の動作については、次の記事で詳しく解説しているので参照してください。
改行コードの判別
改行コードをそのまま読み込めれば判別するのは簡単です。各行の末尾がどの改行コードで終わっているかを確認するだけです。
for line in fin:
if line.endswith('\r\n'):
print('CRLFです。')
elif line.endswith('\n'):
print('LFです。')
elif line.endswith('\r'):
print('CRです。')
else:
print('改行コードがありません')
最初にforループで各行を読み込んでいます。strオブジェクトのendswith()メソッドは文字列が引数の文字列で終わっていればTrueを返し、そうでなければFalseを返しますので、これで行末の文字コードをチェックしています。このコードの場合、「\n」の確認の前に「\r\n」を確認する必要があります。そうでなければ「\r\n」も「\n」で終わっていると判定されてしまいます。
最後のelse節は、行が改行コードで終わっていない場合に実行されます。テキストファイルの末尾が改行コードで終わっていないことを考慮しての処理です。
プログラム全体
一応、わかりやすいようにプログラム全体を載せておきます。行儀よく開いたファイルはクローズします。
fin = open('sample.txt', newline='')
for line in fin:
if line.endswith('\r\n'):
print('CRLFです。')
elif line.endswith('\n'):
print('LFです。')
elif line.endswith('\r'):
print('CRです。')
else:
print('改行コードがありません')
fin.close()
このプログラムの肝は、ファイルの改行コードを変換しないで読み込むことです。
改行コードを判別する際の注意点
実際に文字コードを判別するコードを書く際には、次の2つの点に注意する必要があります。
- すべての行をチェックする
- テキストファイルの末尾が改行コードで終わっていないことを考慮する
行によって改行コード異なるファイルを作成することも可能です。実際、改行コードがLFのファイルの1行をWindows環境で編集したため、その行だけ改行コードがCRLFになって問題が起きたのを見たことがあります。そのため、すべての改行コードが同じであることが保証されていなければ、全行を確認した方が良いでしょう。
2つ目の注意点は、テキストファイルを処理するプログラム全般に言えることですが、ファイルの最後が改行コードで終わっていないファイルも考慮してコードを書くことです。これについては次の記事で考察していますので宜しかったらご参照ください。