在StringIO中进行原地替换

6

如何在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语言解决方案,但更希望使其生效。

1个回答

6

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之前的偏移量,如果找到模式,则会回到上一个偏移量,并写入相同数量的字节。

如果您想使用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。因此,依赖于某个实现或另一个实现将使您的代码不可移植。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接