簡體   English   中英

如何搜索和替換文件中的文本?

[英]How to search and replace text in a file?

如何使用 Python 3 搜索和替換文件中的文本?

這是我的代碼:

import os
import sys
import fileinput

print ("Text to search for:")
textToSearch = input( "> " )

print ("Text to replace it with:")
textToReplace = input( "> " )

print ("File to perform Search-Replace on:")
fileToSearch  = input( "> " )
#fileToSearch = 'D:\dummy1.txt'

tempFile = open( fileToSearch, 'r+' )

for line in fileinput.input( fileToSearch ):
    if textToSearch in line :
        print('Match Found')
    else:
        print('Match Not Found!!')
    tempFile.write( line.replace( textToSearch, textToReplace ) )
tempFile.close()


input( '\n\n Press Enter to exit...' )

輸入文件:

hi this is abcd hi this is abcd
This is dummy text file.
This is how search and replace works abcd

當我在上面的輸入文件中搜索並用“abcd”替換“ram”時,它很有用。 但是當我反之亦然,即用“ram”替換“abcd”時,最后會留下一些垃圾字符。

用“ram”替換“abcd”

hi this is ram hi this is ram
This is dummy text file.
This is how search and replace works rambcd

正如 michaelb958 所指出的,您不能用不同長度的數據替換就地,因為這會使其余部分錯位。 我不同意其他海報建議您從一個文件中讀取並寫入另一個文件。 相反,我會將文件讀入內存,修復數據,然后在單獨的步驟中將其寫出到同一個文件中。

# Read in the file
with open('file.txt', 'r') as file :
  filedata = file.read()

# Replace the target string
filedata = filedata.replace('ram', 'abcd')

# Write the file out again
with open('file.txt', 'w') as file:
  file.write(filedata)

除非您有一個大文件要處理,而該文件太大而無法一次性加載到內存中,或者您擔心如果在將數據寫入文件的第二步過程中過程中斷,則可能會丟失數據。

fileinput已經支持就地編輯。 在這種情況下,它將stdout重定向到文件:

#!/usr/bin/env python3
import fileinput

with fileinput.FileInput(filename, inplace=True, backup='.bak') as file:
    for line in file:
        print(line.replace(text_to_search, replacement_text), end='')

正如 Jack Aidley 發布的和 JF Sebastian 所指出的,這段代碼是行不通的:

 # Read in the file
filedata = None
with file = open('file.txt', 'r') :
  filedata = file.read()

# Replace the target string
filedata.replace('ram', 'abcd')

# Write the file out again
with file = open('file.txt', 'w') :
  file.write(filedata)`

但是這段代碼會起作用(我已經測試過了):

f = open(filein,'r')
filedata = f.read()
f.close()

newdata = filedata.replace("old data","new data")

f = open(fileout,'w')
f.write(newdata)
f.close()

使用這種方法,filein 和 fileout 可以是同一個文件,因為 Python 3.3 將在打開寫入時覆蓋文件。

你可以像這樣進行更換

f1 = open('file1.txt', 'r')
f2 = open('file2.txt', 'w')
for line in f1:
    f2.write(line.replace('old_text', 'new_text'))
f1.close()
f2.close()

您也可以使用pathlib

from pathlib2 import Path
path = Path(file_to_search)
text = path.read_text()
text = text.replace(text_to_search, replacement_text)
path.write_text(text)

(pip 安裝 python-util)

from pyutil import filereplace

filereplace("somefile.txt","abcd","ram")

將所有出現的“abcd”替換為“ram”。
該函數還通過指定regex=True來支持正regex=True

from pyutil import filereplace

filereplace("somefile.txt","\\w+","ram",regex=True)

免責聲明:我是作者( https://github.com/MisterL2/python-util

遲到的答案,但這是我用來在文本文件中查找和替換的內容:

with open("test.txt") as r:
  text = r.read().replace("THIS", "THAT")
with open("test.txt", "w") as w:
  w.write(text)

演示

使用單個 with 塊,您可以搜索和替換您的文本:

with open('file.txt','r+') as f:
    filedata = f.read()
    filedata = filedata.replace('abc','xyz')
    f.truncate(0)
    f.write(filedata)

這個答案對我有用。 以讀取模式打開文件。 以字符串格式讀取文件。 按預期替換文本。 關閉文件。 再次以寫入模式打開文件。 最后,將替換后的文本寫入同一個文件。

    with open("file_name", "r+") as text_file:
        texts = text_file.read()
        texts = texts.replace("to_replace", "replace_string")
    with open(file_name, "w") as text_file:
        text_file.write(texts)
except FileNotFoundError as f:
    print("Could not find the file you are trying to read.")

您的問題源於讀取和寫入同一個文件。 與其打開fileToSearch進行寫入, fileToSearch打開一個實際的臨時文件,然后在完成並關閉tempFile ,使用os.rename將新文件移動到fileToSearch

我的變體,在整個文件中一次一個字。

我讀到了記憶中。

def replace_word(infile,old_word,new_word):
    if not os.path.isfile(infile):
        print ("Error on replace_word, not a regular file: "+infile)
        sys.exit(1)

    f1=open(infile,'r').read()
    f2=open(infile,'w')
    m=f1.replace(old_word,new_word)
    f2.write(m)

我遇到了同樣的問題。 問題在於,當您在變量中加載 .txt 時,您將其用作字符串數組,而它是字符數組。

swapString = []
with open(filepath) as f: 
    s = f.read()
for each in s:
    swapString.append(str(each).replace('this','that'))
s = swapString
print(s)

您可以在 Z23EEEB4347BDD26BDDZ6B7EE9A3B75 中使用 sed 或 awk 或 grep (有一些限制)。 這是一個非常簡單的例子。 它將文件中的香蕉更改為香蕉牙膏。 您可以編輯和使用它。 (我測試過它有效......注意:如果您在 windows 下進行測試,您應該先安裝“sed”命令並設置路徑)

import os 
file="a.txt"
oldtext="Banana"
newtext=" BananaToothpaste"
os.system('sed -i "s/{}/{}/g" {}'.format(oldtext,newtext,file))
#print(f'sed -i "s/{oldtext}/{newtext}/g" {file}')
print('This command was applied:  sed -i "s/{}/{}/g" {}'.format(oldtext,newtext,file))

如果您想在文件上直接查看結果,請應用:“type” for windows/“cat” for linux:

####FOR WINDOWS:
os.popen("type " + file).read()
####FOR LINUX:
os.popen("cat " + file).read()

我建議值得檢查這個小程序。 正則表達式是解決之道。

https://github.com/khranjan/pythonprogramming/tree/master/findandreplace

我已經這樣做了:

#!/usr/bin/env python3

import fileinput
import os

Dir = input ("Source directory: ")
os.chdir(Dir)

Filelist = os.listdir()
print('File list: ',Filelist)

NomeFile = input ("Insert file name: ")

CarOr = input ("Text to search: ")

CarNew = input ("New text: ")

with fileinput.FileInput(NomeFile, inplace=True, backup='.bak') as file:
    for line in file:
        print(line.replace(CarOr, CarNew), end='')

file.close ()

我稍微修改了 Jayram Singh 的帖子,以替換每個 '!' 的實例。 字符到我想隨每個實例遞增的數字。 認為這對於想要修改每行出現不止一次的字符並想要迭代的人可能會有所幫助。 希望能幫助某人。 PS-我在編碼方面很新,所以如果我的帖子有任何不當之處,我深表歉意,但這對我有用。

f1 = open('file1.txt', 'r')
f2 = open('file2.txt', 'w')
n = 1  

# if word=='!'replace w/ [n] & increment n; else append same word to     
# file2

for line in f1:
    for word in line:
        if word == '!':
            f2.write(word.replace('!', f'[{n}]'))
            n += 1
        else:
            f2.write(word)
f1.close()
f2.close()
def word_replace(filename,old,new):
    c=0
    with open(filename,'r+',encoding ='utf-8') as f:
        a=f.read()
        b=a.split()
        for i in range(0,len(b)):
            if b[i]==old:
                c=c+1
        old=old.center(len(old)+2)
        new=new.center(len(new)+2)
        d=a.replace(old,new,c)
        f.truncate(0)
        f.seek(0)
        f.write(d)
    print('All words have been replaced!!!')

除了已經提到的答案,這里解釋了為什么最后有一些隨機字符:
您是在r+模式下打開文件,而不是w模式。 主要區別在於w模式會在您打開文件后立即清除文件內容,而r+不會。
這意味着如果您的文件內容是“123456789”並且您在其中寫入“www”,您將得到“www456789”。 它用新輸入覆蓋字符,但保留任何剩余輸入不變。
您可以使用truncate(<startPosition>)清除文件內容的truncate(<startPosition>) ,但您可能最好先將更新的文件內容保存為字符串,然后執行truncate(0)並一次性寫入所有內容。
或者你可以使用我的圖書館:D

我試過這個並使用 readlines 而不是 read

with open('dummy.txt','r') as file:
    list = file.readlines()
print(f'before removal {list}')
for i in list[:]:
        list.remove(i)

print(f'After removal {list}')
with open('dummy.txt','w+') as f:
    for i in list:
        f.write(i)

使用re.subn可以對替換過程進行更多控制,例如將單詞拆分為兩行,區分大小寫(不區分大小寫)匹配。 此外,它返回匹配的數量,如果找不到字符串,可以使用這些匹配數量來避免資源浪費。

import re

file = # path to file

# they can be also raw string and regex
textToSearch = r'Ha.*O' # here an example with a regex
textToReplace = 'hallo'

# read and replace
with open(file, 'r') as fd:
    # sample case-insensitive find-and-replace
    text, counter = re.subn(textToSearch, textToReplace, fd.read(), re.I)

# check if there is at least a  match
if counter > 0:
    # edit the file
    with open(file, 'w') as fd:
        fd.write(text)

# summary result
print(f'{counter} occurence of "{textToSearch}" were replaced with "{textToReplace}".')

一些正則表達式:

  • 添加re.I標志, re.IGNORECASE的縮寫形式,用於不區分大小寫的匹配
  • 對於多行替換re.subn(r'\n*'.join(textToSearch), textToReplace, fd.read()) ,還取決於數據'\n{,1}' 請注意,對於這種情況, textToSearch必須是純字符串,而不是正則表達式!
def findReplace(find, replace):

    import os 

    src = os.path.join(os.getcwd(), os.pardir) 

    for path, dirs, files in os.walk(os.path.abspath(src)):

        for name in files: 

            if name.endswith('.py'): 

                filepath = os.path.join(path, name)

                with open(filepath) as f: 

                    s = f.read()

                s = s.replace(find, replace) 

                with open(filepath, "w") as f:

                    f.write(s) 

像這樣:

def find_and_replace(file, word, replacement):
  with open(file, 'r+') as f:
    text = f.read()
    f.write(text.replace(word, replacement))

我已將此作為課程練習來解決:打開文件,查找並替換字符串並寫入新文件。

class Letter:

    def __init__(self):

        with open("./Input/Names/invited_names.txt", "r") as file:
            # read the list of names
            list_names = [line.rstrip() for line in file]
            with open("./Input/Letters/starting_letter.docx", "r") as f:
                # read letter
                file_source = f.read()
            for name in list_names:
                with open(f"./Output/ReadyToSend/LetterTo{name}.docx", "w") as f:
                    # replace [name] with name of the list in the file
                    replace_string = file_source.replace('[name]', name)
                    # write to a new file
                    f.write(replace_string)


brief = Letter()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM