zoukankan      html  css  js  c++  java
  • 利用查找替换批处理(附完整源码),进行高效重构

    如果你需要在大量的代码文件中修改某个地方,那么最高效的办法就是使用正则进行批量处理。

    下面介绍一个C#写的查找替换处理程序。

    我本人不喜欢太多的废话,看过功能介绍,各位朋友感兴趣,直接下载小源码包或程序跑一通,就了解了。

    主窗体


    说明

    目录: 指定批处理操作的执行目录。

    子目录:如果勾选,将处理所有子孙级目录的文件。

    文件筛选:与在Windows资源管理器上的搜索文件输入的规则一样。常用的就是星号加后缀名,比如*.cs 。

    查找内容:可输入正则表达式或者文本。

    替换内容:可以输入用于替换的文本。可以使用{N}占位,以进行后向引用操作。N序号从1开始,0表示匹配到的整个字符串。

    正则:勾选,表示使用正则进行处理,否则使用文本进行处理。

    处理结果窗体

     

    双击选项可以打开文件

    代码

     主窗体代码

    View Code
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading;
    using System.Windows.Forms;

    namespace AFReplace
    {
        public partial class FrmAFReplace : Form
        {
            private string _basePath;
            private string _findContent;
            private string _filter;
            private string _replacement;
            private bool _replaceWithRegex;
            private delegate void DealDelegate(string workPath);

            private List<KeyValue> _lsDealFilesResult;
            /// <summary>
            
    /// 查找或替换的操作委托
            
    /// </summary>
            private DealDelegate _delWork;
            /// <summary>
            
    /// 当前是否为替换的处理操作
            
    /// </summary>
            private bool _isReplaceDeal;


            public FrmAFReplace()
            {
                InitializeComponent();
                Icon = Properties.Resources.file_edit_2;
            }

            private void btnReplace_Click(object sender, EventArgs e)
            {
                _isReplaceDeal = true;
                _delWork = ReplaceContent;
                Work();
            }
            private void Work()
            {
                _basePath = txtDirectory.Text;
                if (!Directory.Exists(_basePath))
                {
                    tsslblMessage.Text = "路径不存在";
                    return;
                }

                DirectoryInfo basePathInfo = new DirectoryInfo(_basePath);

                _filter = txtFilter.Text;
                if (string.IsNullOrEmpty(_filter))
                {
                    tsslblMessage.Text = "文件筛选输入为空";
                    return;
                }
                _findContent = txtFindContent.Text;
                if (string.IsNullOrEmpty(_findContent))
                {
                    tsslblMessage.Text = "查找内容输入为空";
                    return;
                }
                _replacement = txtReplaceContent.Text;
                _replaceWithRegex = ckbReplaceWithRegex.Checked;
                _lsDealFilesResult = new List<KeyValue>();
                if (ckbDirectoryItem.Checked)
                {
                    new Thread(() => WorkInDirectoryDeep(basePathInfo)).Start();
                }
                else
                {
                    new Thread(() => WorkInDirectory(basePathInfo)).Start();
                }
            }
            /// <summary>
            
    /// 仅在指定目录替换
            
    /// </summary>
            
    /// <param name="dirInfo"></param>
            private void WorkInDirectory(DirectoryInfo dirInfo)
            {
                WorkByDirectoryInfo(dirInfo);
                WorkedAfter();
            }
            private void WorkByDirectoryInfo(DirectoryInfo dirInfo)
            {
                if (dirInfo.Exists)
                {
                    _delWork(dirInfo.FullName);
                }
            }
            private void WorkedAfter()
            {
                ShowFindResult();
            }
            /// <summary>
            
    /// 深入到子目录替换
            
    /// </summary>
            
    /// <param name="dirInfo"></param>
            private void WorkInDirectoryDeep(DirectoryInfo dirInfo)
            {
                WorkByDirectoryInfo(dirInfo);
                DirectoryInfo[] lsDirInfo = dirInfo.GetDirectories();
                if (lsDirInfo.Length > 0)
                {
                    foreach (DirectoryInfo info in lsDirInfo)
                    {
                        WorkInDirectory(info);
                    }
                }
                else
                {
                    ShowMessage("操作完成");
                    WorkedAfter();
                }
            }
            /// <summary>
            
    /// 在指定目录查找指定文件,并替换,保存。
            
    /// </summary>
            
    /// <param name="workPath"></param>
            private void ReplaceContent(string workPath)
            {
                string[] files = Directory.GetFiles(workPath, _filter);
                string value;
                foreach (string file in files)
                {
                    string content = File.ReadAllText(file);
                    content = _replaceWithRegex ? Regex.Replace(content, _findContent, ReplaceDeal) : content.Replace(_findContent, _replacement);
                    byte[] buffer = Encoding.UTF8.GetBytes(content);
                    if (new FileInfo(file).IsReadOnly)
                    {
                        value = "文件只读 > " + Path.GetFileName(file);
                    }
                    else
                    {
                        File.Delete(file);

                        using (FileStream fs = new FileStream(file, FileMode.Create, FileAccess.Write))
                        {
                            fs.Write(buffer, 0, buffer.Length);
                        }
                        value = "已处理 > " + Path.GetFileName(file);


                    }
                    ShowMessage(value);
                    _lsDealFilesResult.Add(new KeyValue(file, value));
                }
            }
            /// <summary>
            
    /// 在指定目录查找指定文件
            
    /// </summary>
            
    /// <param name="workPath"></param>
            private void FindFiles(string workPath)
            {
                string[] files = Directory.GetFiles(workPath, _filter);
                foreach (string file in files)
                {
                    string content = File.ReadAllText(file);
                    bool isMatch = _replaceWithRegex ? Regex.IsMatch(content, _findContent) : content.Contains(_findContent);
                    if (isMatch)
                    {
                        _lsDealFilesResult.Add(new KeyValue(file, file));
                    }
                }
            }
            /// <summary>
            
    /// 正则替换
            
    /// </summary>
            
    /// <param name="m"></param>
            
    /// <returns></returns>
            private string ReplaceDeal(Match m)
            {
                if (m.Success)
                {
                    MatchCollection mc = Regex.Matches(_replacement, @"{(?<value>\d+)}");
                    List<int> lsValueIndex = new List<int>();
                    foreach (Match match in mc)
                    {

                        int iValueIndex = int.Parse(match.Groups["value"].Value);
                        //序号不可以大于查找到的集合数,总数为匹配()数+自身1
                        if (iValueIndex > m.Groups.Count)
                            throw new Exception("替换的匹配数错误");

                        if (!lsValueIndex.Contains(iValueIndex))
                            lsValueIndex.Add(iValueIndex);
                    }
                    return lsValueIndex.Aggregate(_replacement, (current, i) => current.Replace("{" + i + "}", m.Groups[i].Value));
                }
                return "";
            }
            private void ShowMessage(string msg)
            {
                if (InvokeRequired)
                {
                    Invoke(new MethodInvoker(() => ShowMessage(msg)));
                }
                else
                {
                    tsslblMessage.Text = msg;
                }
            }
            private void ShowFindResult()
            {
                if (InvokeRequired)
                {
                    Invoke(new MethodInvoker(ShowFindResult));
                }
                else
                {
                    new FrmDealResult(_lsDealFilesResult, _isReplaceDeal ? "替换结果" : "查找结果").Show();
                }
            }


            private void lblAbout_Click(object sender, EventArgs e)
            {
                MessageBox.Show("bug及建议提交,请联系alifellod@163.com""查找替换", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

            private void ckbReplaceWithRegex_CheckedChanged(object sender, EventArgs e)
            {
                toolTip1.SetToolTip(txtReplaceContent,
                                    ckbReplaceWithRegex.Checked ? "可以使用{index}进行后向引用,{1}{2}={2}{1}。序号从1开始,0为匹配到的整个值。" : "");
            }

            private void btnFind_Click(object sender, EventArgs e)
            {
                _isReplaceDeal = false;
                _delWork = FindFiles;
                Work();
            }

            private void txtDirectory_TextChanged(object sender, EventArgs e)
            {
                toolTip1.SetToolTip(txtDirectory, txtDirectory.Text.Length > 45 ? txtDirectory.Text : "");
            }

            private void tsslblViewDealList_Click(object sender, EventArgs e)
            {
                ShowFindResult();
            }

            private void btnOpenDirectory_Click(object sender, EventArgs e)
            {
                if (Directory.Exists(txtDirectory.Text))
                {
                    Process.Start(txtDirectory.Text);
                }
            }

            private void btnSelectDirectory_Click(object sender, EventArgs e)
            {
                var fbd = new FolderBrowserDialog();
                if (fbd.ShowDialog() == DialogResult.OK)
                {
                    txtDirectory.Text = fbd.SelectedPath;
                }
            }
        }
    }

    处理结果窗体代码

      

    View Code
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.Windows.Forms;

    namespace AFReplace
    {
        public partial class FrmDealResult : Form
        {
            public FrmDealResult(List<KeyValue> filePtahs, string formTitle)
            {
                InitializeComponent();
                Text = formTitle;
                Icon = Properties.Resources.window;
                if (filePtahs != null && filePtahs.Count > 0)
                {
                    filePtahs.Sort((o1, o2) => String.Compare(o1.Value, o2.Value, StringComparison.Ordinal));

                    lsbResults.DisplayMember = "Value";
                    lsbResults.ValueMember = "Key";
                    lsbResults.DataSource = filePtahs;
                    tsslblMessage.Text = "共计记录: " + filePtahs.Count + " 条";
                }
            }

            public override sealed string Text
            {
                get { return base.Text; }
                set { base.Text = value; }
            }

            private void lsbResults_DoubleClick(object sender, EventArgs e)
            {
                if (lsbResults.SelectedItem != null)
                {
                    string filePath = ((KeyValue)lsbResults.SelectedItem).Key;
                    if (File.Exists(filePath))
                    {
                        Process.Start(filePath);
                    }
                    else
                    {
                        tsslblMessage.Text = "文件不存在";
                    }
                }
            }
        }
    }

     

    辅助类类名

    View Code
    namespace AFReplace
    {
        public class KeyValue
        {
            /// <summary>
            
    /// 保存文件路径
            
    /// </summary>
            public string Key { getset; }
            /// <summary>
            
    /// 显示的文本
            
    /// </summary>
            public string Value { getset; }
            public KeyValue(string key, string value)
            {
                Key = key;
                Value = value;
            }
        }
    }

    下载

    源码下载

    https://files.cnblogs.com/yelaiju/AFReplace_src.rar

    可执行文件下载

    https://files.cnblogs.com/yelaiju/AFReplacer.rar  

  • 相关阅读:
    linux内核启动汇编部分详解
    linux内核zImage详解
    Linux内核zImage怎么来的?
    Linux内核编译make做了什么?
    关于makefile的几点经验
    note
    tmp0000
    tmp
    SSL学习与总结
    C++学习笔记
  • 原文地址:https://www.cnblogs.com/yelaiju/p/3055586.html
Copyright © 2011-2022 走看看