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

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

 

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

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

主窗体


说明

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

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

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

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

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

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

 

处理结果窗体

 

双击选项可以打开文件

代码

 主窗体代码

 

ExpandedBlockStart.gif 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;
            }
        }
    }
}

 

处理结果窗体代码

  

ExpandedBlockStart.gif 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 =  " 文件不存在 ";
                }
            }
        }
    }
}

 

辅助类类名

 

ExpandedBlockStart.gif 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;
        }
    }
}

 

下载

源码下载

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

 

可执行文件下载

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

 

转载于:https://www.cnblogs.com/yelaiju/archive/2013/05/02/3055586.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值