2012-10-26 108 views
24

我是Python新手。我希望能够打开一个文件并通过Python替换某个特定文字的每个实例。举个例子,用'0'代替'zero',用'bob'代替'temp',用'nothing'代替'garbage'。用Python替换文件中的文本

我第一次开始使用这样的:

for line in fileinput.input(fin): 
     fout.write(line.replace('zero', '0')) 
     fout.write(line.replace('temp','bob')) 
     fout.write(line.replace('garbage','nothing')) 

,但我不认为这是做这个的,甚至远程正确的方式。然后,我想了解如果if语句检查这行是否包含这些条目,并且如果它包含这些条目,那么替换该行所包含的条目,但从我所了解的Python中,这也不是真正的理想解决方案。我很想知道什么是最好的方法来做到这一点。提前致谢!

+0

我会做更多的事情,但是这会给我最好的做法做这样的事情。 – shadonar

+1

在您当前的方法中,每个输入行都会被写入输出三次。这是你打算做什么? – Junuxx

+1

另外,你在“bob”后缺少一个撇号。 – Junuxx

回答

63

这应该这样做

replacements = {'zero':'0', 'temp':'bob', 'garbage':'nothing'} 

with open('path/to/input/file') as infile, open('path/to/output/file', 'w') as outfile: 
    for line in infile: 
     for src, target in replacements.iteritems(): 
      line = line.replace(src, target) 
     outfile.write(line) 

编辑:为了解决Eildosa's comment,如果你想做到这一点没有写入另一个文件,那么你最终不得不读你的整个源文件到内存:

lines = [] 
with open('path/to/input/file') as infile: 
    for line in infile: 
     for src, target in replacements.iteritems(): 
      line = line.replace(src, target) 
     lines.append(line) 
with open('path/to/input/file', 'w') as outfile: 
    for line in lines: 
     outfile.write(line) 

编辑:如果您正在使用Python 3.x中,使用replacements.items()代替replacements.iteritems()

+0

您可能想将'outfile.write(line)'移出内部循环...(尽管这是OP代码的直接翻译) – mgilson

+0

通过使用字典(而不是2元组列表),你真的在​​这里获得了什么?这实际上是你用'iteritems()'得到的结果...... – mgilson

+0

你是对的元组。并感谢bugreport – inspectorG4dget

4

的根本途径是

  • read()
  • data = data.replace()往往你需要再
  • write()

如果您一次读取或写入整个数据或更小的部分取决于您。您应该使其取决于预期的文件大小。

read()可以替换为对文件对象的迭代。

6

我可能会考虑使用dictre.sub这样的事情:

import re 
repldict = {'zero':'0', 'one':'1' ,'temp':'bob','garage':'nothing'} 
def replfunc(match): 
    return repldict[match.group(0)] 

regex = re.compile('|'.join(re.escape(x) for x in repldict)) 
with open('file.txt') as fin, open('fout.txt','w') as fout: 
    for line in fin: 
     fout.write(regex.sub(replfunc,line)) 

这有微弱的优势replace,它是更稳健的重叠匹配了一下。

+0

如果OP想要做绝对字符串替换,'re'可能会矫枉过正......或者我错过了什么? – inspectorG4dget

+3

@ inspectorG4dget - 如果有重叠的匹配,这是必要的。 ('line.replace('bob','robert')。replace('robert','foo')')将'bob'改为'foo',这可能不是你想要的,但是你可以用're'来避免。另外,因为它全部完成了,所以它可能更有效率(对于小文件不太重要,但对于大文件很重要)。 – mgilson

2

写这将是比较快的方式...

in = open('path/to/input/file').read() 
out = open('path/to/input/file', 'w') 
replacements = {'zero':'0', 'temp':'bob', 'garbage':'nothing'} 
for i in replacements.keys(): 
    in = in.replace(i, replacements[i]) 
out.write(in) 
out.close 

这消除了不少,其他的答案建议迭代,并会加快更长的文件的过程。

+1

但它读取整个文件(并且基本上每个替换文件都重复一次) - 这对于大文件来说是一个很大的缺点。 – mgilson

+0

另外请注意,这实际上是由@glglgl解决方案的副本... – mgilson

0

从标准输入读取'写入'代码。PY”如下:

import sys 

rep = {'zero':'0', 'temp':'bob', 'garbage':'nothing'} 

for line in sys.stdin: 
    for k, v in rep.iteritems(): 
     line = line.replace(k, v) 
    print line 

然后,重定向或管道执行脚本(http://en.wikipedia.org/wiki/Redirection_(computing)

python code.py <infile> outfile 
5

如果你的文件是短(甚至不是很长),可以使用下面的代码片段在地方,以替换文本:

# Replace variables in file 
with open('path/to/in-out-file', 'r+') as f: 
    content = f.read() 
    f.seek(0) 
    f.truncate() 
    f.write(content.replace('replace this', 'with this')) 
+0

这是我最喜欢的答案,谢谢! – EminezArtus

0

这是我只是用一个短期和简单的例子:

如果:

fp = open("file.txt", "w") 

然后:

fp.write(line.replace('is', 'now')) 
// "This is me" becomes "This now me" 

不:

line.replace('is', 'now') 
fp.write(line) 
// "This is me" not changed while writing