批量文本内容查找替换字符串工具

'''python写代码,tkinter实现UI用户交互界面,导入xml.etree.ElementTree模块解析xml格式文件。
功能:
用户单击“浏览”执行browse_folder_path()函数,打开文件夹,
用户输入待查找字符串(用户单选框Checkbutton选择是否大小写敏感),
用户输入字符串重复出现的次数(用户单选框Combobox选择:等于,大于,小于),
用户输入替换字符串或中文字符,
用户单击“开始查找”执行search_files()函数,遍历文件夹和子文件夹内所有.txt和.xml格式文件,如果出现xml文件内容格式不正确,跳过该文件。
将查找结果返回显示,如果没有符合的结果,显示“搜索无果!”
用户单击“开始替换”执行replace_files()函数,询问用户:直接替换,另存为。将search_files()函数查找的结果进行字符串替换。
注意使用中文表达,不要写注释'''
import os
import tkinter as tk
from tkinter import filedialog
from tkinter import messagebox
from tkinter import ttk

import xml.etree.ElementTree as ET
import markdown

selected_filetypes = []
folder_path = ''

#---
# folder_dir = ''
# search_string = ''
# case_sensitive = ''
# search_count = 1
# search_type = ''
# replace_string = ''
#----

def browse_folder_path():
    global folder_path
    folder_selected = filedialog.askdirectory()
    folder_path.set(folder_selected)


def search_files():
    folder_dir = folder_path.get()
    search_string = search_string_entry.get()
    case_sensitive = case_sensitive_var.get()
    search_count = int(search_count_entry.get())
    search_type = search_type_var.get()
    global selected_filetypes

    if not os.path.isdir(folder_dir):
        messagebox.showerror("错误", "文件夹路径无效")
        return

    search_results.delete(1.0, tk.END)  # 清空文本框

    if xml_var.get():
        selected_filetypes.append('.xml')
    if txt_var.get():
        selected_filetypes.append('.txt')
    if py_var.get():
        selected_filetypes.append('.py')
    if yaml_var.get():
        selected_filetypes.append('.yaml')
    if md_var.get():
        selected_filetypes.append('.md')

    found_files = []

    for root, dirs, files in os.walk(folder_dir):
        for file in files:
            file_ext = os.path.splitext(file)[1].lower()  # 获取文件的后缀并转为小写
            # 另一种写法:if file.endswith(('.txt', '.xml')):括号内用tuple()元组
            if file_ext in selected_filetypes:
                file_path = os.path.join(root, file)  # file_path形如input.yaml,也就是文件名
                text = ""

                if file_ext == '.xml':
                    with open(file_path, 'r', encoding='utf-8') as xml_file:
                        tree = ET.parse(xml_file)
                        root_element = tree.getroot()
                        for element in root_element.iter():
                            text += element.text + " "
                            # element.text = ET.tostring(root, encoding='utf-8').decode()  # todo
                elif file_ext == '.txt':
                    with open(file_path, 'r', encoding='utf-8', errors='ignore') as txt_file:
                        text = txt_file.read()
                elif file_ext == '.py':
                    with open(file_path, 'r', encoding='utf-8', errors='ignore') as py_file:
                        text = py_file.read()
                elif file_ext == '.yaml':
                    with open(file_path, 'r', encoding='utf-8', errors='ignore') as yaml_file:
                        # yaml_data = yaml.load(yaml_file, Loader=yaml.FullLoader)
                        # text = yaml.dump(yaml_data)
                        text = yaml_file.read()
                elif file_ext == '.md':
                    with open(file_path, 'r', encoding='utf-8', errors='ignore') as md_file:
                        text = md_file.read()
                        text = markdown.markdown(text)

                if not case_sensitive:
                    text = text.lower()
                    search_string = search_string.lower()
                count = text.count(search_string)

                if (search_type == "=" and count == search_count) or \
                        (search_type == ">" and count > search_count) or \
                        (search_type == "<" and count < search_count):
                    found_files.append(file_path)

    if found_files:
        search_results.insert(tk.END, "找到以下文件匹配搜索条件:\n")
        for file_path in found_files:
            search_results.insert(tk.END, file_path + "\n")
        search_results.insert(tk.END, "\n")
    else:
        search_results.insert(tk.END, "搜索无果!\n")

    replace_button.config(state=tk.NORMAL)


def replace_files():
    folder_dir = folder_path.get()
    search_string = search_string_entry.get()
    case_sensitive = case_sensitive_var.get()
    replace_string = replace_string_entry.get()

    if not os.path.isdir(folder_dir):
        messagebox.showerror("错误", "文件夹路径无效")
        return

    for root, dirs, files in os.walk(folder_dir):
        for file in files:
            file_ext = os.path.splitext(file)[1].lower()
            if file_ext in selected_filetypes:
                file_path = os.path.join(root, file)
                text = ""

                # if file_ext == '.xml':
                #         tree = ET.parse(file_path)
                #         root = tree.getroot()
                #         text = ET.tostring(root, encoding='utf-8').decode()#字符串转中文utf-8编码
                if file_ext == '.xml':
                    with open(file_path, 'r', encoding='utf-8') as xml_file:
                        tree = ET.parse(xml_file)
                        root_element = tree.getroot()
                        for element in root_element.iter():
                            text += element.text + " "
                            # element.text = ET.tostring(root, encoding='utf-8').decode()  # todo
                elif file_ext == '.txt':
                    with open(file_path, 'r', encoding='utf-8', errors='ignore') as txt_file:
                        text = txt_file.read()
                elif file_ext == '.py':
                    with open(file_path, 'r', encoding='utf-8', errors='ignore') as py_file:
                        text = py_file.read()
                elif file_ext == '.yaml':
                    with open(file_path, 'r', encoding='utf-8', errors='ignore') as yaml_file:
                        # yaml_data = yaml.load(yaml_file, Loader=yaml.FullLoader)#todo
                        # text = yaml.dump(yaml_data)
                        text = yaml_file.read()
                elif file_ext == '.md':
                    with open(file_path, 'r', encoding='utf-8', errors='ignore') as md_file:
                        text = md_file.read()
                        text = markdown.markdown(text)

                if not case_sensitive:
                    text = text.lower()
                    search_string = search_string.lower()

                new_text = text.replace(search_string, replace_string)

                if file_ext == '.xml':
                    with open(file_path, 'r', encoding='utf-8', errors='ignore') as xml_file:
                        tree = ET.parse(xml_file)
                        root_element = tree.getroot()
                        for element in root_element.iter():
                            if search_string in element.text:
                                element.text = element.text.replace(search_string, replace_string)
                        tree.write(file_path, encoding='utf-8')  # todo encoding='utf-8'表明写入的编码格式为中文

                elif file_ext == '.txt':
                    with open(file_path, 'w', encoding='utf-8', errors='ignore') as new_txt_file:
                        new_txt_file.write(new_text)
                elif file_ext == '.py':
                    with open(file_path, 'w', encoding='utf-8', errors='ignore') as new_py_file:
                        new_py_file.write(new_text)
                elif file_ext == '.yaml':
                    with open(file_path, 'w', encoding='utf-8', errors='ignore') as new_yaml_file:
                        new_yaml_file.write(new_text)
                elif file_ext == '.md':
                    with open(file_path, 'w', encoding='utf-8', errors='ignore') as new_md_file:
                        new_md_file.write(new_text)

    search_results.insert(tk.END, "替换完成\n")
def reset():

    folder_entry.delete(0,'end')
    search_count_entry.delete(0,'end')
    replace_string_entry.delete(0, 'end')
    search_string_entry.delete(0, 'end')
# 创建主窗口
root = tk.Tk()
root.iconbitmap(r'F:\kdy.ico')
root.title("文件查找和替换工具v1.0 by zsp")
# grid默认居中排布,w表示左对齐,e表示右对齐,sticky=N+W+W+E  拉高并拉长组件,让组件填充满一个表格框。
# 文件夹路径变量
folder_path = tk.StringVar()
# 创建文件夹选择按钮和输入框
folder_label = tk.Label(root, text="选择文件夹:")
folder_label.grid(row=0, column=0, sticky="e")
folder_entry = tk.Entry(root, width=20, textvariable=folder_path)
folder_entry.grid(row=0, column=1)
folder_button = tk.Button(root, text="浏览", fg='#CD70FF', command=browse_folder_path)
folder_button.grid(row=0, column=2, sticky="w")

# 创建搜索字符串输入框
search_string_label = tk.Label(root, text="查找字符串:")
search_string_label.grid(row=1, column=0, sticky="e")
search_string_entry = tk.Entry(root, width=20)
search_string_entry.grid(row=1, column=1)

# 创建大小写敏感选择框
case_sensitive_var = tk.BooleanVar()
case_sensitive_checkbox = tk.Checkbutton(root, text="Aa", variable=case_sensitive_var)
case_sensitive_checkbox.grid(row=1, column=2, sticky="w")

# 创建搜索次数和类型输入框,初始化值1
num = tk.StringVar(value=1)
search_count_label = tk.Label(root, text="重复次数:")
search_count_label.grid(row=2, column=0, sticky="e")
search_count_entry = tk.Entry(root, width=20, textvariable=num)
search_count_entry.grid(row=2, column=1)

search_type_var = tk.StringVar()
search_type_combobox = ttk.Combobox(root, width=3, textvariable=search_type_var, values=["=", ">", "<"])
search_type_combobox.set("=")
search_type_combobox.grid(row=2, column=2, sticky="w")

# 创建替换字符串输入框
replace_string_label = tk.Label(root, text="替换字符串:")
replace_string_label.grid(row=3, column=0, sticky="e")
replace_string_entry = tk.Entry(root, width=20)
replace_string_entry.grid(row=3, column=1)


# 创建搜索结果文本框
search_results = tk.Text(root, width=60, height=10)
search_results.grid(row=5, column=0, columnspan=3, sticky="e")

# LabelFrame标签框架
labelFrame = tk.LabelFrame(root, text="文件类型")
labelFrame.grid(row=4, column=0, columnspan=3)

# 创建复选框来选择文件类型

md_var = tk.BooleanVar()
md_checkbox = tk.Checkbutton(labelFrame, text=".md", variable=md_var)
md_checkbox.grid(row=0, column=0, sticky="w")

py_var = tk.BooleanVar()
py_checkbox = tk.Checkbutton(labelFrame, text=".py", variable=py_var)
py_checkbox.grid(row=0, column=1, sticky="w")

txt_var = tk.BooleanVar()
txt_checkbox = tk.Checkbutton(labelFrame, text=".txt", variable=txt_var)
txt_checkbox.grid(row=0, column=2, sticky="w")

xml_var = tk.BooleanVar()
xml_checkbox = tk.Checkbutton(labelFrame, text=".xml", variable=xml_var)
xml_checkbox.grid(row=0, column=3, sticky="w")

yaml_var = tk.BooleanVar()
yaml_checkbox = tk.Checkbutton(labelFrame, text=".yaml", variable=yaml_var)
yaml_checkbox.grid(row=0, column=4, sticky="w")

# 创建开始查找按钮
search_button = tk.Button(root, text="开始查找", font=('times', 12, 'bold'), fg='#00ff00', command=search_files)
search_button.grid(row=6, column=0, pady=10, sticky='NSEW')

# 创建开始替换按钮
replace_button = tk.Button(root, text="开始替换", font=('times', 12, 'bold'), fg='#ff0000', command=replace_files,
                           state=tk.DISABLED)
replace_button.grid(row=6, column=1, pady=10, sticky='NSEW')

# 创建开始清除按钮
reset_button = tk.Button(root, text="清除", font=('times', 12, 'bold'), fg='#0000ff', command=reset)
reset_button.grid(row=6, column=2, pady=10, sticky='NSEW')

# 启动主循环
root.mainloop()

效果

尚且不支持doc,pdf之类的格式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值