How do I replace a string with another inside a StringIO
? - I've heard it's possible if they're the same length.
Attempt:
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: Currently working on a solution in C, but would much rather make this work.
The StringIO module is an in-memory file-like object. This object can be used as input or output to the most function that would expect a standard file object. When the StringIO object is created it is initialized by passing a string to the constructor. If no string is passed the StringIO will start empty.
The documentation says: StringIO. close() : Free the memory buffer. Attempting to do further operations with a closed StringIO object will raise a ValueError.
StringIO
tries to mock up a regular file in read/write, except that it's stored in memory. You have the same issues when trying to edit a text file in-place than with a regular file (replacing by longer string overwrites the following line). You also have the same options.
Small other change: cStringIO
created with a default string at start is not writable. But you can workaround this by creating an empty object and write to it (you obviously have access to a write
method now)
What you're looking for:
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()
It stores the offset before the lineread and if pattern is found, it seeks back to the previous offset, and writes the same number of bytes
Brutal solution if you want to use cStringIO
: you can read the buffer fully, perform your replace, and write back to it (allows replacing by longer strings), but reads the whole buffer, which is probably not what you want:
c = 'can\nhaz\nfoo'
sio = StringIO(c)
v = sio.getvalue()
v = v.replace("haz","bar")
sio.seek(0)
sio.write(v)
Note that Python 3 removed those objects, now it's just io
. So relying on such or such implementation will make your code non-portable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With