在Python中多次找到行时,如何仅查找和替换一次行

在Python中多次找到行时,如何仅查找和替换一次行,python,replace,find,Python,Replace,Find,我有三个列表:filePath、textToFind、textToReplace。我需要在给定的文件路径打开每个文件,找到一行并替换一行。列表总是按顺序排列,并且长度总是相同的。代码如下: for i, path in enumerate(filePath): for line in fileinput.input(path, inplace=1): sys.stdout.write(line.replace(textToFind[i], textToReplace[i]))

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

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个列表上使用
zip
,可避免携带索引)

编辑:在与另一个答案的作者进行了一次小讨论后,我认为他的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)

你需要检测什么时候有东西需要替换。如果找到,则标记,但继续写入其余行,否则将截断文件

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

编辑:在与另一个答案的作者进行了一次小讨论后,我认为他的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)

我的解决方案的优雅程度大大降低了。然而,我仍然想提供一个临时文件的替代方案

# 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)

我的解决方案的优雅程度大大降低了。然而,我仍然想提供一个临时文件的替代方案

# 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)

作为对您实际问题的回答:

“如何在Python中多次找到行时只查找和替换一次行”

具有一个可选的
maxreplace
选项,用于限制要替换的出现次数。根据:

字符串。替换(s,旧的,新的[,maxreplace])

返回字符串s的副本,其中所有出现的子字符串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

作为对您实际问题的回答:

“如何在Python中多次找到行时只查找和替换一次行”

具有一个可选的
maxreplace
选项,用于限制要替换的出现次数。根据:

字符串。替换(s,旧的,新的[,maxreplace])

返回字符串s的副本,其中所有出现的子字符串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

您的意思是说您想用
textToFind
textToFind
中相应的索引项替换
filePath
的每个索引处的文件吗?或者,在
filePath
中存在的所有文件中,所有
textToFind
。我想用textToFind和textToReplace中相应的索引替换filePath的每个索引。filePath和textToFind并不总是唯一的,但textToReplace总是唯一的。您的意思是说您想用
textToFind
textToFind
中相应的索引项替换
filePath
的每个索引处的文件吗?或者,在
filePath
中存在的所有文件中,所有
textToFind
。我想用textToFind和textToReplace中相应的索引替换filePath的每个索引。filePath和textToFind并不总是唯一的,但是textToReplace总是唯一的。这不是在文件中写回。我喜欢你不使用标志的优雅方式,只需中断第一个替换循环,然后简单地迭代到最后。我将编辑您的答案,使其回答问题。实际上,
fileinput.input
使用临时文件。因此,您的解决方案也很好(我必须查找
fileinput
模块)。我向您借用了双
for
循环,因为它更好。这不是在文件中写回我喜欢您不使用标志的优雅方式,只需中断第一个替换循环并简单地迭代到最后。我将编辑您的答案,使其回答问题。实际上,
fileinput.input
使用临时文件。因此,您的解决方案也很好(我必须查找
fileinput
模块)。我向你借了双
for
循环,因为它更好。