我想循环一个文本文件的内容,并在一些行上进行搜索和替换,并将结果写回文件。我可以先把整个文件加载到内存中,然后再把它写回来,但这可能不是最好的方法。

在下面的代码中,做到这一点的最佳方法是什么?

f = open(file)
for line in f:
    if line.contains('foo'):
        newline = line.replace('foo', 'bar')
        # how to write this newline back to the file

当前回答

扩展@Kiran的回答,我认为它更简洁和python化,这增加了编解码器来支持UTF-8的读写:

import codecs 

from tempfile import mkstemp
from shutil import move
from os import remove


def replace(source_file_path, pattern, substring):
    fh, target_file_path = mkstemp()

    with codecs.open(target_file_path, 'w', 'utf-8') as target_file:
        with codecs.open(source_file_path, 'r', 'utf-8') as source_file:
            for line in source_file:
                target_file.write(line.replace(pattern, substring))
    remove(source_file_path)
    move(target_file_path, source_file_path)

其他回答

创建一个新文件,将行从旧文件复制到新文件,并在将行写入新文件之前执行替换操作。

我想像这样的东西就可以了。它基本上将内容写入一个新文件,并用新文件替换旧文件:

from tempfile import mkstemp
from shutil import move, copymode
from os import fdopen, remove

def replace(file_path, pattern, subst):
    #Create temp file
    fh, abs_path = mkstemp()
    with fdopen(fh,'w') as new_file:
        with open(file_path) as old_file:
            for line in old_file:
                new_file.write(line.replace(pattern, subst))
    #Copy the file permissions from the old file to the new file
    copymode(file_path, abs_path)
    #Remove original file
    remove(file_path)
    #Move new file
    move(abs_path, file_path)

正如lassevk所建议的,在运行时写出新文件,下面是一些示例代码:

fin = open("a.txt")
fout = open("b.txt", "wt")
for line in fin:
    fout.write( line.replace('foo', 'bar') )
fin.close()
fout.close()

扩展@Kiran的回答,我认为它更简洁和python化,这增加了编解码器来支持UTF-8的读写:

import codecs 

from tempfile import mkstemp
from shutil import move
from os import remove


def replace(source_file_path, pattern, substring):
    fh, target_file_path = mkstemp()

    with codecs.open(target_file_path, 'w', 'utf-8') as target_file:
        with codecs.open(source_file_path, 'r', 'utf-8') as source_file:
            for line in source_file:
                target_file.write(line.replace(pattern, substring))
    remove(source_file_path)
    move(target_file_path, source_file_path)

使用hamishmcn的答案作为模板,我能够在文件中搜索与我的正则表达式匹配的一行,并将其替换为空字符串。

import re 

fin = open("in.txt", 'r') # in file
fout = open("out.txt", 'w') # out file
for line in fin:
    p = re.compile('[-][0-9]*[.][0-9]*[,]|[-][0-9]*[,]') # pattern
    newline = p.sub('',line) # replace matching strings with empty string
    print newline
    fout.write(newline)
fin.close()
fout.close()