如何将多行字符串分成多行?


287

我有一个多行字符串文字,我想在每一行上执行一个操作,如下所示:

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

我想做以下事情:

for line in inputString:
    doStuff()

Answers:


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

与上面的相同,但是不建议使用字符串模块的功能,应避免使用:

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

16
inputString.split(os.linesep)将使用平台特定的行终止符。
詹姆斯

10
奇怪的是,这个答案如此之高。硬编码'\ n'是一个坏主意,但是即使您使用os.linesep代替它,您也会在Linux上遇到Windows行尾的问题,反之亦然,等等。此外,它使用True参数来促进分割线是可能是不太常用的使用方式...
lpapp 2014年

4
次优方法,不建议使用的方法以及最优方法的多余变形的组合。
jwg 2015年

50

使用str.splitlines()

splitlines()不同于,可以正确处理换行符split("\n")

它也具有@efotinis提到的优点,当使用True参数调用时,可以在拆分结果中选择性地包括换行符。


为什么不应该使用的详细说明split("\n")

\n在Python中,代表Unix换行符(ASCII十进制代码10),独立于运行它的平台。但是,换行表示形式取决于平台。在Windows上,\n是两个字符CRLF(ASCII十进制码13和10,\r\n称为AKA 和),而在任何现代Unix(包括OS X)上,它都是单个字符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')在带有Windows文件的UNIX系统中使用将导致不良行为。同样,使用与其他来源(例如来自套接字)的换行符可能不同的字符串来处理字符串也很常见。


这种比较是不公平的,因为您也可以使用split(os.linesep)来避免平台特定的位。
lpapp 2014年

6
@lpapp注意,splitlines它将在任何行尾分割。split(os.linesep)在unix中读取Windows文件时将失败,例如
goncalopp

1
在我的情况下,使用分割线的另一个原因是,谢谢。我给了+1。我个人甚至会将评论中的信息纳入您的答案。
lpapp 2014年

20

在这种特殊情况下可能会过大,但另一个选择涉及使用StringIO创建文件状对象

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

是的,这是最惯用的,最Python化的方法。
顺磁牛角包

4
与相比,此方法的优点str.split不需要分配任何内存(它就地读取字符串)。缺点是使用时速度要慢得多StringIO(大约50倍)。cStringIO但是,
goncalopp 2014年

比什么快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()
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.