【问题标题】:Python readline() from a string?来自字符串的Python readline()?
【发布时间】:2011-09-19 14:52:25
【问题描述】:

在 python 中,有没有内置的方法来对字符串执行 readline()?我有一大块数据,想只去掉前几行而不对整个字符串执行 split()。

假设示例:

def handleMessage(msg):
   headerTo  = msg.readline()
   headerFrom= msg.readline()
   sendMessage(headerTo,headerFrom,msg)

msg = "Bob Smith\nJane Doe\nJane,\nPlease order more widgets\nThanks,\nBob\n"
handleMessage(msg)

我希望这会导致: sendMessage("Bob Smith", "Jane Doe", "Jane,\nPlease order...")

我知道编写一个这样做的类相当容易,但如果可能的话,我正在寻找内置的东西。

编辑:Python v2.7

【问题讨论】:

    标签: python


    【解决方案1】:

    在 Python 3 中,您可以使用 io.StringIO:

    >>> msg = "Bob Smith\nJane Doe\nJane,\nPlease order more widgets\nThanks,\nBob\n"
    >>> msg
    'Bob Smith\nJane Doe\nJane,\nPlease order more widgets\nThanks,\nBob\n'
    >>>
    >>> import io
    >>> buf = io.StringIO(msg)
    >>> buf.readline()
    'Bob Smith\n'
    >>> buf.readline()
    'Jane Doe\n'
    >>> len(buf.read())
    44
    

    在 Python 2 中,您可以使用 StringIO(如果性能很重要,则可以使用 cStringIO):

    >>> import StringIO
    >>> buf = StringIO.StringIO(msg)
    >>> buf.readline()
    'Bob Smith\n'
    >>> buf.readline()
    'Jane Doe\n'
    

    【讨论】:

    • 完美。 buf.read() 读取一定数量的行后,缓冲区还剩下什么。
    • 为什么要为 buf 分配额外的内存?
    【解决方案2】:

    python 2 和 3 最简单​​的方法是使用字符串的方法splitlines()。这会返回一个行列表。

    >>> "some\nmultilene\nstring\n".splitlines()
    

    ['some', 'multilene', 'string']

    【讨论】:

    • 而且 str.splitlines() 是跨平台的,不管像 \r\n 或 \n 这样的行尾样式。
    • 我认为这比接受的答案更方便。
    【解决方案3】:

    为什么不只根据需要进行多次拆分?由于您正在使用所有结果部分(包括字符串的其余部分),将其加载到其他缓冲区对象中,然后再次将其读回可能会更慢,而不是更快(加上函数调用的开销) .

    如果您想将第一行 N 分开,只需执行 .split("\n", N)

    >>> foo = "ABC\nDEF\nGHI\nJKL"
    >>> foo.split("\n", 1)
    ['ABC', 'DEF\nGHI\nJKL']
    >>> foo.split("\n", 2)
    ['ABC', 'DEF', 'GHI\nJKL']
    

    所以对于你的功能:

    def handleMessage(msg):
       headerTo, headerFrom, msg = msg.split("\n", 2)
       sendMessage(headerTo,headerFrom,msg)
    

    或者如果你真的想变得花哨:

    # either...
    def handleMessage(msg):
       sendMessage(*msg.split("\n", 2))
    
    # or just...
    handleMessage = lambda msg: sendMessage(*msg.split("\n", 2))
    

    【讨论】:

    • 如果您不介意处理异常和/或检查 split 附带的数组长度并且您知道要提前读取多少行,则此方法有效。我不知道提前有多少标题行。也许我的例子过于琐碎。
    • 如果您正在检查事情,那么是的,StringIO 可能是您最好的选择。 (不用担心:示例 - 构建适当的示例通常会在简化和不丢失上下文之间取得平衡。)
    【解决方案4】:

    像 StringIO 那样做:

    i = self.buf.find('\n', self.pos)
    

    所以这意味着:

    pos = msg.find("\n")
    first_line = msg[:pos]
    ...
    

    似乎比使用整个 StringIO 更优雅...

    【讨论】:

      【解决方案5】:

      在 Python 字符串中有方法分割线

      msg = "Bob Smith\nJane Doe\nJane,\nPlease order more widgets\nThanks,\nBob\n"
      msg_splitlines = msg.splitlines()
      headerTo = msg_splitlines[0]
      headerFrom= msg_splitlines[1]
      sendMessage(headerTo,headerFrom,msg)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-14
        • 1970-01-01
        • 2010-10-13
        相关资源
        最近更新 更多