複数行の文字列を複数の行に分割するにはどうすればよいですか?


287

次のように、各行で操作を実行する複数行の文字列リテラルがあります。

inputString = """Line 1
Line 2
Line 3"""

次のようなことをしたい:

for line in inputString:
    doStuff()

回答:


437
inputString.splitlines()

各アイテムのリストを提供します。このsplitlines()メソッドは、各行をリスト要素に分割するように設計されています。


12
+1。これは、行の区切り記号を明示的に乱さないため、受け入れられているソリューションよりも優れていると思います。すべてが専用のAPIメソッドで動作します!
lpapp 2014

12
@lpapp、私は完全に同意します。splitlines()は、意味的に(そして機能的には、ユニバーサル改行を使用し、後続の空行を省略しているため)split( '\ n')よりも優れています。当時(2008年)私はPythonistaの初心者でしたが、私のスクリプトでは、splitlines()をほぼ独占的に使用していることがわかりました。したがって、104ポイントの回答(* sob ... *)を削除し、代わりにこの回答を承認します。
efotinis 2014

18
これもとは異なり''.splitlines() == []、に['']なり''.split('\n')ます。
2014

198

他の人が言ったように:

inputString.split('\n')  # --> ['Line 1', 'Line 2', 'Line 3']

これは上記と同じですが、stringモジュールの関数は非推奨であり、避ける必要があります。

import string
string.split(inputString, '\n')  # --> ['Line 1', 'Line 2', 'Line 3']

または、各行にブレークシーケンス(CR、LF、CRLF)を含める場合は、 splitlinesメソッドにTrue引数を指定してます。

inputString.splitlines(True)  # --> ['Line 1\n', 'Line 2\n', 'Line 3']

12
これは、「\ n」を行末記号として使用するシステムでのみ機能します。
ジェレミーカントレル

20
@Jeremy:三重引用符で囲まれた文字列リテラルは、プラットフォームに関係なく、常に「\ n」EOLを使用します。そのため、ファイルはテキストモードで読み取られます。
efotinis 2008年

16
inputString.split(os.linesep)プラットフォーム固有の行終端記号を使用します。
James

10
この答えがとても賛成されているのは奇妙です。ハードコーディング '\ n'は悪い考えですが、その代わりにos.linesepを使用した場合でも、Linuxでのウィンドウの行末やその逆などで問題が発生します。おそらくあまり一般的ではない方法
lpapp '27

4
次善の方法、非推奨の方法、および最適な方法の冗長バリエーションの組み合わせ。
jwg

50

を使用しstr.splitlines()ます。

splitlines()とは異なり、は改行を適切に処理しますsplit("\n")

また、@ efotinisで言及されているように、True引数で呼び出されたときに分割結果に改行文字をオプションで含めるという利点もあります。


使用すべきでない理由の詳細な説明split("\n")

\nPythonでは、実行するプラットフォームとは関係なく、Unixの改行(ASCII 10進コード10)を表します。ただし、改行の表現はプラットフォームに依存します。Windowsでは\n2文字でCRありLF(ASCII 10進コード13と10、AKA \rおよび\n)、最新のUnix(OS Xを含む)では1文字LFです。

printたとえば、プラットフォームに一致しない行末の文字列がある場合でも正しく動作します。

>>> print " a \n b \r\n c "
 a 
 b 
 c

ただし、「\ n」で明示的に分割すると、プラットフォームに依存する動作になります。

>>> " a \n b \r\n c ".split("\n")
[' a ', ' b \r', ' c ']

あなたが使用している場合でもos.linesep、それだけで、あなたのプラットフォーム上での改行区切りに応じて分割され、あなたが他のプラットフォームで作成したテキストを処理し、または裸にしている場合に失敗します\n

>>> " a \n b \r\n c ".split(os.linesep)
[' a \n b ', ' c ']

splitlines これらすべての問題を解決します:

>>> " a \n b \r\n c ".splitlines()
[' a ', ' b ', ' c ']

テキストモードでファイルを読み取ると、Python \nがプラットフォームの改行表現に変換されるため、改行表現の問題が部分的に緩和されます。ただし、テキストモードはWindowsにのみ存在します。UNIXシステムでは、すべてのファイルがバイナリモードで開かれるためsplit('\n')、UNIXシステムでWindowsファイルを使用すると、望ましくない動作が発生します。また、ソケットなどの他のソースとは改行が異なる可能性のある文字列を処理することも珍しくありません。


プラットフォーム固有のビットを回避するためにsplit(os.linesep)も使用できるため、比較は公平ではありません。
lpapp 14

6
@lpappノートsplitlinesに分割されます任意のラインエンディング。split(os.linesep)たとえば、UNIXでWindowsファイルを読み取ると失敗します
goncalopp

1
私の場合に分割線を使用するもう1つの理由、ありがとう。+1しました。個人的にはコメントの情報も回答に組み込んでいます。
lpapp 2014

20

この特定のケースではやり過ぎかもしれませんが、別のオプションにはStringIO、ファイルのようなオブジェクトを作成するためのの使用が含まれます

for line in StringIO.StringIO(inputString):
    doStuff()

はい、これは最も慣用的で最もPython的なアプローチです。
常磁性クロワッサン2014

4
この方法の利点は、と比較するとstr.splitメモリを割り当てる必要ないことです(文字列をインプレースで読み取ります)。欠点は、使用するとかなり遅くなることですStringIO(約50倍)。cStringIOただし、
goncalopp

何より2倍速い?
イリーナラポ

1
@ IrinaRapoport、cStringIOはStringIOより2倍高速です
iruvar

1

元の投稿は、いくつかの行(ある条件に該当する場合)と次の行を出力するコードを要求しました。私の実装はこれです:

text = """1 sfasdf
asdfasdf
2 sfasdf
asdfgadfg
1 asfasdf
sdfasdgf
"""

text = text.splitlines()
rows_to_print = {}

for line in range(len(text)):
    if text[line][0] == '1':
        rows_to_print = rows_to_print | {line, line + 1}

rows_to_print = sorted(list(rows_to_print))

for i in rows_to_print:
    print(text[i])

0

@ 1_CRの回答にはより多くのバンプが必要であり、彼の回答を増やしたいので、コメントに適切なコードテキスト形式を設定したいと思います。とにかく、彼は私を次のテクニックに導いてくれました。使用可能な場合はcStringIOを使用します(ただし、cStringIOとStringIOは同じではありません。これは、cStringIOをサブクラス化できないためです...組み込みです...しかし、基本的な操作の構文は同じであるため、これを行うことができます):

try:
    import cStringIO
    StringIO = cStringIO
except ImportError:
    import StringIO

for line in StringIO.StringIO(variable_with_multiline_string):
    pass
print line.strip()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.