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

下面介绍一个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 { get; set; }
        /// <summary>
        /// 显示的文本
        /// </summary>
        public string Value { get; set; }
        public KeyValue(string key, string value)
        {
            Key = key;
            Value = value;
        }
    }
}

下载

源码下载:

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

可执行文件下载:

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

利用查找替换批处理(附完整源码),进行高效重构相关推荐

  1. JavaScript实现Interpolation search插值查找算法(附完整源码)

    JavaScript实现Interpolation search插值查找算法(附完整源码) interpolationSearch.js完整源代码 interpolationSearch.test.j ...

  2. JavaScript实现binarySearch二分查找算法(附完整源码)

    JavaScript实现binarySearch二分查找算法(附完整源码) Comparator.js完整源代码 binarySearch.js完整源代码 binarySearch.test.js完整 ...

  3. java 制作动态手机壁纸_android 动态切换壁纸实例 利用service机制实现 附完整源码 带动态截图...

    [实例简介]通过点击 startService实现 android手机动态壁纸功能 [实例截图] [核心代码] main.xml android:orientation="vertical& ...

  4. JavaScript实现使用 BITWISE 方法查找集合的幂集算法(附完整源码)

    JavaScript实现使用 BITWISE 方法查找集合的幂集算法(附完整源码) bwPowerSet.js完整源代码 bwPowerSet.test.js完整源代码 bwPowerSet.js完整 ...

  5. C++实现二分查找(附完整源码)

    实现二分查找完整源码 二分查找(折半查找) 非递归 完整源码 递归 完整源码 二分查找(折半查找) 对于已排序,若无序,需要先排序 非递归 完整源码 int BinarySearch(vector&l ...

  6. A*寻路算法,循序渐进,附完整源码

    A*寻路算法-循序渐进(附完整源码) 用途 ​ A*寻路算法的一般用途即为灵活地寻找初始点到目标点的最短路径. 概述 ​ 灵活是A*算法更为注重的特性,可以任意添加障碍物,可以对不同地形的寻路损耗赋予 ...

  7. Python实现恩尼格玛加密算法——附完整源码

    Python实现恩尼格玛加密算法--附完整源码 恩尼格玛是第二次世界大战中德国所使用的复杂电机械式密码机.它被认为是世界上最复杂的加密设备之一.在这个项目中,我们将使用Python模拟实现恩尼格玛加密 ...

  8. android 静态图片自动切换,Android静态图片人脸识别的完整demo(附完整源码)

    Android静态图片人脸识别的完整demo(附完整源码) 来源:互联网 作者:佚名 时间:2015-03-24 20:07 本文介绍了android静态识别人脸并进行标记人眼位置及人脸框的完整dem ...

  9. JavaScript实现唯一路径问题的动态编程方法的算法(附完整源码)

    JavaScript实现唯一路径问题的动态编程方法的算法(附完整源码) dpUniquePaths.js完整源代码 dpUniquePaths.test.js完整源代码 dpUniquePaths.j ...

最新文章

  1. 好货不能错过!一款在GitHub上22k+star的人力资源管理系统
  2. druid mysql配置详解_druid配置详解
  3. kindeditor编辑器和图片上传独立分开的配置细节
  4. OpenCV中的神器Image Watch
  5. Oracle数据库日常管理之数据备份,恢复及迁移 (第五讲 )
  6. PLSQL 实现split
  7. 35岁腾讯员工:准备退休!1kw房产+1kw股票+3百万现金,勉强够用了
  8. C# 自己绘制报表,GDI你会用吗?
  9. CSDN免费获得积分和直接获取下载码的方法,亲测有效
  10. linux深度商店 apt,Deepin系统安装软件总结:通过商店、二进制包、deb包、终端命令安装...
  11. 在2003服务器上预览时出现:您未被授权查看该页 您不具备使用所提供的凭据查看该目录或页的权限
  12. numpy使用np.dot函数或者@操作符计算两个numpy数组的点积数量积(dot product、scalar product)
  13. [Evolutionary Algorithm] 进化算法简介
  14. 测试智商多高的软件,智商测试:测测你的智商多高
  15. 关闭windows server 2016弹出交互式服务检测窗口
  16. 用python画小仓鼠教程_小仓鼠简笔画教程
  17. 抖音C#版,自己抓第三方抖音网站
  18. MATLAB小知识(三)——输出矩阵到TXT
  19. 为什么那么多程序员害怕Python?
  20. 记C#和C++混合开发的坑们

热门文章

  1. 揭秘|超乎想象!未来50年将出现的九大黑科技……
  2. 如何衡量机器与人类的智能关系,AI智商评测标准专家研讨会邀请
  3. 过年期间:这个 GitHub 项目你必能用到
  4. ​计算产业如何加速突破?鲲鹏开发者技术沙龙带来新答案
  5. Windows 10 太难用,如何定制你的 Ubuntu?
  6. 最高补助1000万元!这类程序员2020年要过好日子了……
  7. IBM服务器49Y4230选件网卡在安装ESXI4.x认不到驱动参考
  8. pyenv、pipenv 环境管理
  9. 使用rancher 搭建docker集群
  10. linux系统管理工具sar(一)