如果你需要在大量的代碼文件中修改某個地方,那么最高效的辦法就是使用正則進行批量處理。
下面介紹一個C#寫的查找替換處理程序。
我本人不喜歡太多的廢話,看過功能介紹,各位朋友感興趣,直接下載小源碼包或程序跑一通,就了解了。
主窗體
說明
目錄: 指定批處理操作的執行目錄。
子目錄:如果勾選,將處理所有子孫級目錄的文件。
文件篩選:與在Windows資源管理器上的搜索文件輸入的規則一樣。常用的就是星號加后綴名,比如*.cs 。
查找內容:可輸入正則表達式或者文本。
替換內容:可以輸入用於替換的文本。可以使用{N}占位,以進行后向引用操作。N序號從1開始,0表示匹配到的整個字符串。
正則:勾選,表示使用正則進行處理,否則使用文本進行處理。
處理結果窗體
雙擊選項可以打開文件
代碼
主窗體代碼

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;
}
}
}
}
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;
}
}
}
}
處理結果窗體代碼

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 = " 文件不存在 ";
}
}
}
}
}
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 = " 文件不存在 ";
}
}
}
}
}
輔助類類名

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;
}
}
}
{
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