【问题标题】:How do I split a multi-line string into multiple lines?如何将多行字符串拆分为多行?
【发布时间】:2010-09-15 09:44:07
【问题描述】:

我有一个多行字符串,我想对每一行进行操作,如下所示:

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

我想在每一行上迭代:

for line in inputString:
    doStuff()

【问题讨论】:

    标签: python string split


    【解决方案1】:

    使用inputString.splitlines()。


    为什么splitlines 更好

    splitlines 可以正确处理换行符,这与 split 不同。

    当使用True 参数调用时,它还可以选择在拆分结果中返回换行符,这在某些特定场景中很有用。


    为什么你不应该使用split("\n")

    在跨操作系统共享文件时,使用split 会产生非常混乱的错误。

    \n 在 Python 中表示 Unix 换行符(ASCII 十进制代码 10),与运行它的操作系统无关。但是,the ASCII linebreak representation is OS-dependent。

    在 Windows 上,\n 是两个字符,CR 和 LF(ASCII 十进制代码 13 和 10,\r 和 \n),而在现代 Unix(Mac OS X、Linux、Android)上,是单个字符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 ']
    

    Reading files in text mode 部分缓解了换行表示问题,因为它将 Python 的 \n 转换为平台的换行表示。

    但是,文本模式仅存在于 Windows 上。在 Unix 系统上,所有文件都以二进制模式打开,因此在带有 Windows 文件的 UNIX 系统中使用 split('\n') 会导致不良行为。在网络中传输文件时也会发生这种情况。

    【讨论】:

    • 比较不公平,因为您也可以使用 split(os.linesep) 来避免平台特定位。
    • @lpapp 请注意,splitlines 将在 any 行结尾处拆分。 split(os.linesep)在unix中读取windows文件时会失败,例如
    • 在我的情况下使用分割线的另一个原因,谢谢。我给了+1。我个人什至会将 cmets 中的信息合并到您的答案中。
    【解决方案2】:
    inputString.splitlines()
    

    会给你一个包含每个项目的列表,splitlines() 方法旨在将每一行拆分为一个列表元素。

    【讨论】:

    • +1。我认为这比公认的解决方案更好,因为它不会明确地与行分隔符混淆。这一切都只适用于专用的 API 方法!
    • @lpapp,我完全同意。 splitlines() 在语义上(和功能上,因为它使用通用换行符并省略尾随空行)比 split('\n') 更好。那时(2008 年)我只是一个新手 Pythonista,虽然我的脚本现在显示我也几乎完全使用 splitlines()。因此,我删除了我的 104 分答案 (*sob...*),并将改为支持这个答案。
    • 这也是''.splitlines() == [],而不是[''],就像''.split('\n')一样。
    【解决方案3】:

    请求代码的原始帖子打印一些行(如果它们在某些条件下为真)加上下一行。 我的实现是这样的:

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

    【讨论】:

      【解决方案4】:

      就像其他人说的:

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

      这与上面的相同,但字符串模块的功能已被弃用,应避免使用:

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

      或者,如果您希望每一行都包含中断序列(CR、LF、CRLF),请使用带有True 参数的splitlines 方法:

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

      【讨论】:

      • 这仅适用于使用 '\n' 作为行终止符的系统。
      • @Jeremy:三引号字符串文字总是使用 '\n' EOL,无论平台如何。以文本模式读取文件也是如此。
      • inputString.split(os.linesep) 将使用平台特定的行终止符。
      • 奇怪的是,这个答案如此受欢迎。硬编码 '\n' 是个坏主意,但即使你使用 os.linesep 代替它,你也会在 Linux 上遇到 Windows 行结束问题,反之亦然,等等。此外,它正在使用 True 参数促进分割线,即可能是不太常见的使用方式......
      • 次优方法、弃用方法和最优方法的冗余变体的组合。
      【解决方案5】:

      我希望 cmets 有正确的代码文本格式,因为我认为 @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()
      

      【讨论】:

        【解决方案6】:

        在这种特殊情况下可能有点矫枉过正,但另一种选择是使用 StringIO 创建类似文件的对象

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

        【讨论】:

        • 是的,这是最惯用的、最 Python-ic 的方法。
        • 与str.split 相比,此方法的一个优势是不需要分配任何内存(它就地读取字符串)。一个缺点是,如果您使用StringIO(大约 50 倍),它会慢得多。但是,如果您使用 cStringIO,它的速度大约会快 2 倍
        • 比什么快 2 倍?
        • @IrinaRapoport,cStringIO 比 StringIO 快 2 倍
        猜你喜欢
        • 2016-12-31
        • 1970-01-01
        • 2011-08-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多