没有python re模块替换字符串?

时间:2016-12-05 04:04:21

标签: python

说我的文件如下:

foo
bar
BeginObject
something
something
ObjectAlias NotMe
lines
more lines
BeginKeyframe 22 12   
foo
bar default
foo default
bar default
EndKeyframe
EndObject
foo
bar
BeginObject
something
something
ObjectAlias HeyThere
lines
more lines
BeginKeyframe 43243 12   
foo
bar default
foo default
bar default
foo default
bar default
foo default
bar
EndKeyframe
EndObject

我想要一行:

BeginKeyframe 43243 12

替换为:

BeginKeyframe 6 12 

注意: 6是"默认"以及BeginKeyframe和EndKeyframe

我的第一个版本的python代码有一些交互问题。见here
感谢sloth和Skycc,一个改进的版本正在运行。见here
现在的适用是改进的代码使用re模块来实现,这不是我想要的,我更喜欢将原始文件逐行复制到新文件而不会覆盖原始文件。
所以我的问题是如何改进Skycc的代码?

objectlist = ['GoodMoring', 'GoodAfternoon']
with open('input.txt', 'r+') as f:
    line = f.readline()
    pos = f.tell()
    found = False
    while line:
        found = found or any('ObjectAlias ' + objectname in line for objectname in objectlist)
        if 'EndObject' in line:
            found = False
        if found and 'BeginKeyframe' in line:
            sub_line = f.readline()
            frames = 0
            while not 'EndKeyframe' in sub_line:
                if 'default' in sub_line:
                    frames += 1
                sub_line = f.readline()
            pos2 = f.tell()
            f.seek(pos)
            f.write(re.sub('\d+', str(frames), line, count=1))
            f.seek(pos2)
        pos = f.tell()
        line = f.readline()

2 个答案:

答案 0 :(得分:1)

完整代码:

interested_objects = ['HeyThere', 'anotherone',]

buff = []
obj_flag = False
keyframe_flag = False

with open('in') as f, open ('out', 'w') as of:
    for line in f:
        line = line.strip()

        if line.startswith('ObjectAlias'):
            assert not obj_flag
            assert not keyframe_flag
            if line.split()[1] in interested_objects:
                obj_flag = True

        if not obj_flag:
            print >>of, line
            continue

        if 'EndObject' in line:
            assert not keyframe_flag
            obj_flag = False

        if 'BeginKeyframe' in line:
            assert not keyframe_flag
            keyframe_flag = True

        if keyframe_flag:
            buff.append(line)
        else:
            print >>of, line

        if 'EndKeyframe' in line:
            parts = buff[0].split()
            new_line = '{} {} {}'.format(parts[0], len(buff)-2, parts[2])
            print >>of, new_line
            print >>of, '\n'.join(buff[1:])
            buff = []
            keyframe_flag = False

答案 1 :(得分:0)

只需以'w'模式打开input.txt以进行只读,然后打开另一个文件output.txt并使用seek模式写入新文件。并且不需要tellobjectlist = ['GoodMoring', 'GoodAfternoon'] with open('input.txt', 'r') as f, open('output.txt', 'w') as fo: found = False begin_frame = False buffer = [] for line in f: if line.startswith('ObjectAlias'): found = any('ObjectAlias ' + objectname in line for objectname in objectlist) elif line.startswith('EndObject'): if found and begin_frame: # modify and write all buffer into output file buffer[0] = buffer[0].replace(buffer[0].split()[1], str(frames), 1) for i in buffer: fo.write(i) buffer = [] # clear buffer found = False begin_frame = False elif line.startswith('BeginKeyframe'): begin_frame = True frames = 0 if found and begin_frame: buffer.append(line) if 'default' in line: frames += 1 else: fo.write(line) ,只需在读取输入文件时逐行处理它。

一旦找到BeginKeyFrame,就会使用缓冲区来保留这些行。找到EndObject时将缓冲区释放到输出文件。

快速编辑如下代码,应该有效但可能不那么优雅和pythonic

{{1}}