如何在Python中多次查找和替换行一次

时间:2016-11-19 14:04:59

标签: python replace find

我有三个列表:filePath,textToFind,textToReplace。我需要在给定的filePath处打开每个文件,找到一行并替换一行。列表始终按顺序排列,长度始终相同。代码如下:

for i, path in enumerate(filePath):
   for line in fileinput.input(path, inplace=1):
      sys.stdout.write(line.replace(textToFind[i], textToReplace[i]))

问题是textToFind可以在文件中多次找到,因此该代码用textToReplace的当前索引位置替换它找到的所有文本。我需要它在第一次找到项目时中断,然后继续下一次迭代。我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:2)

您需要检测何时需要更换的内容。如果找到,请标记,但继续写其余行,否则您将截断该文件。

(请注意,在3个列表中使用zip可以避免携带索引)

for path,find,replace in zip(filePath,textToFind,textToReplace):    
   match_found = False
   for line in fileinput.input(path, inplace=1):
      if match_found:
         # keep writing the rest of lines, unchanged
         sys.stdout.write(line)
      else:
         # try to replace
         rep = line.replace(find, replace)
         sys.stdout.write(rep)
         if line!=rep:
             # flag: don't replace anything till the end
             match_found = True
编辑:经过与另一个答案的作者的小讨论,我认为他的2循环模式比带有标志的1更好,所以我借用它,节省了对标志的需要,必须稍快一点:

for path,find,replace in zip(filePath,textToFind,textToReplace):
   handle = fileinput.input(path, inplace=1)
   for line in handle:
     rep = line.replace(find, replace)
     sys.stdout.write(rep)
     if line!=rep:
        break
   for line in handle:
      sys.stdout.write(line)

答案 1 :(得分:2)

我的解决方案在优雅方面明显减少了。但是,我仍然想提供一个带有临时文件的替代方案。

# loop over every path, thing to find and replacement in the lists
for path, needle, replacement in zip(filePath, textToFind, textToReplace):
   with open(path) as read_handle:
       with open(path + '.tmp', 'w+') as write_handle:
            # first print and replace
            for line in read_handle:
                 write_handle.write(line.replace(needle, replacement))

                 # if we found something
                 if needle in line:
                     break # quit this the inner for-loop

            # the remaining lines should be printed without modification
            for line in read_handle:
                  write_handle.write(line)
    # overwrite the file with the temporary file
    shutil.move(path + '.tmp', path)

答案 2 :(得分:0)

作为您实际问题的答案:

  

"如何在Python" 中多次找到和替换一次行。

str.replace()有一个可选的maxreplace选项,用于限制要替换的事件数。根据{{​​3}}:

  

string.replace(s,old,new [,maxreplace])

     

返回字符串s的副本,其中所有出现的substring old都替换为new。 如果给出了可选参数maxreplace,则替换第一个maxreplace事件。

例如:

>>> my_test_string = 'Hello Hello Hello'

#                                            v  maxreplace as `1`
>>> my_test_string.replace('Hello', 'World', 1)
'World Hello Hello'
# ^ Only first word is replaced