【问题标题】:in-place replacement in StringIOStringIO 中的就地替换
【发布时间】:2017-04-11 04:09:46
【问题描述】:

如何将StringIO 中的字符串替换为另一个字符串? - 我听说如果它们的长度相同,这是可能的。

尝试:

from cStringIO import StringIO

c = 'can\nhaz\nfoo'

sio = StringIO(c)

for line in sio:
    if line == 'haz\n':
        # sio.write('bar\n')
        line = 'bar\n'
        break

sio.seek(0)
sio.readlines()   # [ 'can\n', 'haz\n', 'bar' ]

PS:目前正在研究 C 中的解决方案,但更愿意完成这项工作。

【问题讨论】:

    标签: python python-2.7 python-internals stringio cstringio


    【解决方案1】:

    StringIO 尝试以读/写方式模拟常规文件,但它存储在内存中。尝试就地编辑文本文件时,您会遇到与使用常规文件相同的问题(替换为更长的字符串会覆盖以下行)。你也有同样的选择。

    其他小的变化:cStringIO 在开始时使用默认字符串创建是不可写的。但是你可以通过创建一个空对象并写入它来解决这个问题(你现在显然可以访问write 方法)

    你在找什么:

    c = 'can\nhaz\nfoo'
    
    sio = StringIO()
    sio.write(c)
    sio.seek(0)
    
    offset = sio.tell()
    for line in sio:
        if line == 'haz\n':
            sio.seek(offset)
            sio.write('bar\n')
            break
        offset = sio.tell()
    

    它存储 lineread 之前的偏移量,如果找到pattern,它会回溯到前一个偏移量,并写入相同数量的字节

    如果你想使用cStringIO,那么残酷的解决方案:你可以完全读取缓冲区,执行替换,然后写回它(允许用更长的字符串替换),但是读取整个缓冲区,这可能不是你想要的想要:

    c = 'can\nhaz\nfoo'
    
    sio = StringIO(c)
    
    v = sio.getvalue()
    v = v.replace("haz","bar")
    sio.seek(0)
    sio.write(v)
    

    请注意,Python 3 删除了这些对象,现在它只是 io。所以依赖这样或这样的实现会使你的代码不可移植。

    【讨论】:

      猜你喜欢
      • 2020-05-27
      • 2017-01-06
      • 1970-01-01
      • 2019-10-13
      • 2016-05-06
      • 2015-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多