用VC_2010制作基于正则表达式的查找替换工具
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
(3) 编 写 一 个 函 数 changeFileName, 用 于 改 变 文 件 名 称 ,
它所生成的新文件名称是由旧文件名称加上计算机当前时间
所组成:
CString changeFileName( const CString& oldFileName ) {
time_t t; time(&t); CString sTime( _tctime(&t) ) ; sTime.Replace( ' ', '_' ); sTime.Replace( ':', '-' ); sTime = sTime.Mid( 4, 15 ); CString fileName = oldFileName ; fileName = fileName.Mid(0, fileName.ReverseFind('.') ); CString newFileName = fileName + " (" + sTime + "). txt";
正则表达式由原子和运算符组成。 原子指定要查找的内容 以及在文本中进行匹配的位置。 运算符不是所有表达式都必须 的, 它把原子结合到复杂的表达式中。 正则表达式中的原子有 单个字符、 点、 类、 锚和向后引用等 5 种类型, 运算符也有序 列、 替换、 重复、 组、 保存、 非保存圆括号、 向前查找、 向后 查找等 8 种类型。 严格来说, 正则表达式并非一种编程语言, 与 脚 本 语 言 JavaScript 和 VBScript 类 似 , 它 只 能 在 一 种 合 适 的 编 程 语 言 的 环 境 下 使 用 。 C#、 Java、 Visual Basic .NET 中 都 可 以 使 用 正 则 表 达 式 。 如 果 想 要 在 Visual C++ 6.0 中 使 用 正 则 表 达 式 , 需 要 另 外 安 装 包 含 正 则 表 达 式 功 能 的 boost 库 , 其 安 装 过 程 非 常 繁 琐 。 而 Visual C++ 2010 的 模 板 库 中 引 入 了 正 则 表 达式, 无需再安装。
3.2 在对话框中放置控件
在对话框中放置如图 1 所示的各个控件, 在表 1 中, 按照 从左到右, 从上到下的顺序对这些控件的类型、 ID、 标题、 相 关变量、 作用等作了具体的介绍。
表 1 各个控件的类型、 ID、 标题、 相关变量、 作用
控件类型 ID
控件标题
相关变量 作用
命令按钮 IDC_BUTTON1 源文件名:
Visual C++ 2010 提供了两个正则表达式的编程接口, 一个 是 使 用 Unicode 宽 字 节 字 符 集 (wregex); 另 一 个 是 ANSI 多 字 节字符集 (regex)。 为了适应用户的普遍认知习惯, 比如把字母 “A” 和汉字 “中” 都分别看作一个字符, 而不是把 “A” 看作 一个字符, 却把 “中” 看作 两 个 字 符 , 所 以 选 用 Unicode 字 符 集 编 程 接 口 。 Unicode 字 符 集 是 国 际 通 用 字 符 集 , 然 而 计 算 机 中现有 的 文 本 文 件 大 部 分 是 以 ANSI 字 符 集 编 码 存 储 的 , 所 以 在编程时需要转化字符编码, 以多字节读入, 然后它们映射为 宽字节字符, 再使用正则表达式完成处理任务, 最后转化为多 字节字符输出。
图 1 查找替换工具的 “查找” 功能
图 2 查找替换工具的 “匹配” 功能
42 2012. 17
FORUM OF EXPERTS
专家论坛
图 3 查找替换工具的 “替换” 功能
3 编程实现
3.1 新建项目
启 动 Visual Studio 2010 , 在 “ 文 件 ” 菜 单 上 , 指 向 “ 新 建 ”, 然 后 单 击 “项 目 ” 打 开 “新 建 项 目 ” 对 话 框 。 从 Visual C++ 项目列表中选择 “MFC 应 用 程 序 ”, 在 “名 称 ” 框 中 键 入 “regularExpress”, 然后单击 “确定” 按钮。 在 “MFC 应用程序 向导” 的 “应用程序类型” 中, 选择 “基于对话框”, 然后多 次点击 “下一步”, 最后点击 “完成” 即可。 本项目的字符集 要设置为 “使用 Unicode 字符集”, 这项设置可在 “项目---属 性---配置属性---常规---字符集” 中找到。
m_showTarg 关信息 提示 显示 “保存处理后信 息的文件名称”
另 外 , 为 了 得 到 美 观 大 方 的 显 示 效 果 , 要 修 改 ID 为
IDC_EDIT4 和 IDC_EDIT5 两 个 编 辑 框 控 件 的 外 观 属 性 , 把 它
们属性中的 “自动水平滚动” 设置为 “假”, “自动垂直滚动”
1 引言
1956 年 , 数 学 家 Stephen Kleene 发 表 了 一 篇 论 文 , 名 为 《神经网事件的表示法》, 其中使用了正则表达式的概念。 在此 之前, 神经生理学家 McCulloch 和 Pitts 就已经用正则表达式来 描述神经网络。 一个正则表达式就是一个模式, 它是由与文本 进行匹配的字符序列组成。 通过判断模式与文本是否匹配, 来 决定表达式的真假。 它提供了一种从字符集合中搜寻特定字符 串的机制, 同时也提供了一种以其他内容来替换所搜寻到的字 符串的机制。
if(nLength <= 0) return string(""); char *szbuffer = new char[nLength + 2]; ::WideCharToMultiByte (CP_OEMCP, 0, wstrsrc.c_str(), -1, szbuffer, nLength, NULL, NULL); string strnew = szbuffer; delete [] szbuffer; return strnew; }
(2) 标题为 “查找” 命令按钮的单击响应消息
UpdateData(true); if ( m_origFile == "" || m_editRegExpress == "" ) { MessageBox(_T("请先选择源文件并且输入正则表达式") );
return; } CString newFile = changeFileName( m_origFile ); ifstream inFile( m_origFile ); ofstream outFile( newFile ); if( ! inFile || ! outFile ) { MessageBox(_T("cannot open the infile or create outFile") ); } string strLine; wstring wstrLine; int count = 1, numLine = 0; m_showTarg = _T(""); wregex reg( m_editRegExpress ); while( getline( inFile, strLine ) ) {
命令按钮 IDC_MATCH 匹配
匹配符合条件的文本
编辑框 IDC_EDIT3
m_erep 编辑用于替换的文本
命令按钮 IDC_REPLACE 替换
替换符合条件的文本
编辑框 IDC_EDIT4 编辑框 IDC_EDIT5 命令按钮 IDC_BUTTON4 目标文件名: 编辑框 IDC_EDIT6
m_showOrig 显示源文件的内容 显示经过处理后的相
(2) 函 数 Unicode2Ansi; 功 能 是 把 Unicode 编 码 的 宽 字 符
串转化为 ANSI 编码的多字节字符串:
string Unicode2Ansi(wstring wstrsrc) {
int nLength = ::WideCharToMultiByte (CP_ACP, 0, wstrsrc.c_str(), -1, NULL, 0, NULL, NULL);
2012. 17 43
实用第一 智慧密集
return newFileName; }
3.4 添加各个命令按钮的单击响应消息
(1) 标题为 “浏览” 命令按钮的单击响应消息
CFileDialog OpenFileDlg (true, _T (""),_T (""), OFN_OVERWRITEPROMPT);
实用第一 智慧密集
用 VC++ 2010 制作基于正则表达式的查找替换工具
马创新
摘 要: 介绍了使用 VC++ 2010 制作基于正则表达式的查找替换工具的方法。 使用该方法制作的 查找替换工具美观大方、 简易实用。 文中所有代码均在 VC++ 2010 下测试通过, 具有很强的可移 植性和健壮性。 关键词: VC++ 2010 版; 正则表达式; 查找; 替换; Unicode 编码
if(OpenFileDlg.DoModal()! =IDOK) return;
this->m_origFile=OpenFileDlg.GetPathName(); if ( m_origFile == "" )
return; ifstream inFile( m_origFile ); if( ! inFile )
MessageBox(_T("cannot open the infile ") ); string strLine; wstring wstrLine; m_showOrig = _T(""); while( getline( inFile, strLine ) ) {
wstrLine = Ansi2Unicode( strLine ); m_showOrig = m_showOrig + wstrLine.c_str () + _T("\r\r\n"); } UpdateData(FALSE); UpdateWindow(); inFile.close();
2 功能及特点
查找替换工具提供了 “查找”、 “匹配” 和 “替换” 3 种 功能。 “查找” 功能的界面如图 1 所示; “匹配” 功能的界面 如图 2 所示; “替换” 功能的界面如图 3 所示。 使用这个程序 时, 首先点击 “浏览” 按钮打开 “文件选择对话框”, 从中选 择需要处理的文本文件 (后 缀 名 为 txt), 用 户 选 择 之 后 , 该 文 本文件中的内容就会在界面左下方的编辑控件中显示出来; 然 后编辑正则表达式, 如果要使用 “替换” 功能, 还要在 “替 换” 命令按钮前面的编辑框中输入要替换的内容; 最后根据任 务需要点击 “查找”、 “匹配” 和 “替换” 3 个命令按钮之一, 程序就可以把符合条件的文本在界面右下方的编辑框中显示出 来, 并且保存处理后的文本到一个新的文件中, 这个新文件的 名称会在界面最下方的编辑框中显示出来。
设置为 “真”, “垂直滚动” 设置为 “真”, “多行” 设置为
“真”。 其他控件均使用默认设置。
3.3 编写调用函数代码
(1) 函 数 Ansi2Unicode; 功 能 是 把 ANSI 编 码 的 多 字 节 字
符串转化为 Unicode 编码的宽字符串:
wstring Ansi2Unicode(string astrsrc) { int nLength = ::MultiByteToWideChar ( CP_ACP, 0, astrsrc.c_str(), -1, NULL, 0); if(nLength <= 0) return wstring(L""); wchar_t *szbuffer = new wchar_t[nLength + 2]; ::MultiByteToWideChar (CP_ACP, 0, astrsrc.c_str (), -1, szbuffer, nLength); wstring strnew = szbuffer; delete [] szbuffer; return strnew; }
提示
编辑框 IDC_EDIT1 命令按钮 IDC_BUTTON2 浏览
m_origFile
显示用户所选择的文 件名 打开文件选择对话框, 选择文件
命令按钮 IDC_BUTTON3 编辑正则表达式:
提示
编辑框 IDC_EDIT2
m_ere
编辑和显示正则表达式
命令按钮 IDC_SEARCH 查找
查找符合条件的文本
它所生成的新文件名称是由旧文件名称加上计算机当前时间
所组成:
CString changeFileName( const CString& oldFileName ) {
time_t t; time(&t); CString sTime( _tctime(&t) ) ; sTime.Replace( ' ', '_' ); sTime.Replace( ':', '-' ); sTime = sTime.Mid( 4, 15 ); CString fileName = oldFileName ; fileName = fileName.Mid(0, fileName.ReverseFind('.') ); CString newFileName = fileName + " (" + sTime + "). txt";
正则表达式由原子和运算符组成。 原子指定要查找的内容 以及在文本中进行匹配的位置。 运算符不是所有表达式都必须 的, 它把原子结合到复杂的表达式中。 正则表达式中的原子有 单个字符、 点、 类、 锚和向后引用等 5 种类型, 运算符也有序 列、 替换、 重复、 组、 保存、 非保存圆括号、 向前查找、 向后 查找等 8 种类型。 严格来说, 正则表达式并非一种编程语言, 与 脚 本 语 言 JavaScript 和 VBScript 类 似 , 它 只 能 在 一 种 合 适 的 编 程 语 言 的 环 境 下 使 用 。 C#、 Java、 Visual Basic .NET 中 都 可 以 使 用 正 则 表 达 式 。 如 果 想 要 在 Visual C++ 6.0 中 使 用 正 则 表 达 式 , 需 要 另 外 安 装 包 含 正 则 表 达 式 功 能 的 boost 库 , 其 安 装 过 程 非 常 繁 琐 。 而 Visual C++ 2010 的 模 板 库 中 引 入 了 正 则 表 达式, 无需再安装。
3.2 在对话框中放置控件
在对话框中放置如图 1 所示的各个控件, 在表 1 中, 按照 从左到右, 从上到下的顺序对这些控件的类型、 ID、 标题、 相 关变量、 作用等作了具体的介绍。
表 1 各个控件的类型、 ID、 标题、 相关变量、 作用
控件类型 ID
控件标题
相关变量 作用
命令按钮 IDC_BUTTON1 源文件名:
Visual C++ 2010 提供了两个正则表达式的编程接口, 一个 是 使 用 Unicode 宽 字 节 字 符 集 (wregex); 另 一 个 是 ANSI 多 字 节字符集 (regex)。 为了适应用户的普遍认知习惯, 比如把字母 “A” 和汉字 “中” 都分别看作一个字符, 而不是把 “A” 看作 一个字符, 却把 “中” 看作 两 个 字 符 , 所 以 选 用 Unicode 字 符 集 编 程 接 口 。 Unicode 字 符 集 是 国 际 通 用 字 符 集 , 然 而 计 算 机 中现有 的 文 本 文 件 大 部 分 是 以 ANSI 字 符 集 编 码 存 储 的 , 所 以 在编程时需要转化字符编码, 以多字节读入, 然后它们映射为 宽字节字符, 再使用正则表达式完成处理任务, 最后转化为多 字节字符输出。
图 1 查找替换工具的 “查找” 功能
图 2 查找替换工具的 “匹配” 功能
42 2012. 17
FORUM OF EXPERTS
专家论坛
图 3 查找替换工具的 “替换” 功能
3 编程实现
3.1 新建项目
启 动 Visual Studio 2010 , 在 “ 文 件 ” 菜 单 上 , 指 向 “ 新 建 ”, 然 后 单 击 “项 目 ” 打 开 “新 建 项 目 ” 对 话 框 。 从 Visual C++ 项目列表中选择 “MFC 应 用 程 序 ”, 在 “名 称 ” 框 中 键 入 “regularExpress”, 然后单击 “确定” 按钮。 在 “MFC 应用程序 向导” 的 “应用程序类型” 中, 选择 “基于对话框”, 然后多 次点击 “下一步”, 最后点击 “完成” 即可。 本项目的字符集 要设置为 “使用 Unicode 字符集”, 这项设置可在 “项目---属 性---配置属性---常规---字符集” 中找到。
m_showTarg 关信息 提示 显示 “保存处理后信 息的文件名称”
另 外 , 为 了 得 到 美 观 大 方 的 显 示 效 果 , 要 修 改 ID 为
IDC_EDIT4 和 IDC_EDIT5 两 个 编 辑 框 控 件 的 外 观 属 性 , 把 它
们属性中的 “自动水平滚动” 设置为 “假”, “自动垂直滚动”
1 引言
1956 年 , 数 学 家 Stephen Kleene 发 表 了 一 篇 论 文 , 名 为 《神经网事件的表示法》, 其中使用了正则表达式的概念。 在此 之前, 神经生理学家 McCulloch 和 Pitts 就已经用正则表达式来 描述神经网络。 一个正则表达式就是一个模式, 它是由与文本 进行匹配的字符序列组成。 通过判断模式与文本是否匹配, 来 决定表达式的真假。 它提供了一种从字符集合中搜寻特定字符 串的机制, 同时也提供了一种以其他内容来替换所搜寻到的字 符串的机制。
if(nLength <= 0) return string(""); char *szbuffer = new char[nLength + 2]; ::WideCharToMultiByte (CP_OEMCP, 0, wstrsrc.c_str(), -1, szbuffer, nLength, NULL, NULL); string strnew = szbuffer; delete [] szbuffer; return strnew; }
(2) 标题为 “查找” 命令按钮的单击响应消息
UpdateData(true); if ( m_origFile == "" || m_editRegExpress == "" ) { MessageBox(_T("请先选择源文件并且输入正则表达式") );
return; } CString newFile = changeFileName( m_origFile ); ifstream inFile( m_origFile ); ofstream outFile( newFile ); if( ! inFile || ! outFile ) { MessageBox(_T("cannot open the infile or create outFile") ); } string strLine; wstring wstrLine; int count = 1, numLine = 0; m_showTarg = _T(""); wregex reg( m_editRegExpress ); while( getline( inFile, strLine ) ) {
命令按钮 IDC_MATCH 匹配
匹配符合条件的文本
编辑框 IDC_EDIT3
m_erep 编辑用于替换的文本
命令按钮 IDC_REPLACE 替换
替换符合条件的文本
编辑框 IDC_EDIT4 编辑框 IDC_EDIT5 命令按钮 IDC_BUTTON4 目标文件名: 编辑框 IDC_EDIT6
m_showOrig 显示源文件的内容 显示经过处理后的相
(2) 函 数 Unicode2Ansi; 功 能 是 把 Unicode 编 码 的 宽 字 符
串转化为 ANSI 编码的多字节字符串:
string Unicode2Ansi(wstring wstrsrc) {
int nLength = ::WideCharToMultiByte (CP_ACP, 0, wstrsrc.c_str(), -1, NULL, 0, NULL, NULL);
2012. 17 43
实用第一 智慧密集
return newFileName; }
3.4 添加各个命令按钮的单击响应消息
(1) 标题为 “浏览” 命令按钮的单击响应消息
CFileDialog OpenFileDlg (true, _T (""),_T (""), OFN_OVERWRITEPROMPT);
实用第一 智慧密集
用 VC++ 2010 制作基于正则表达式的查找替换工具
马创新
摘 要: 介绍了使用 VC++ 2010 制作基于正则表达式的查找替换工具的方法。 使用该方法制作的 查找替换工具美观大方、 简易实用。 文中所有代码均在 VC++ 2010 下测试通过, 具有很强的可移 植性和健壮性。 关键词: VC++ 2010 版; 正则表达式; 查找; 替换; Unicode 编码
if(OpenFileDlg.DoModal()! =IDOK) return;
this->m_origFile=OpenFileDlg.GetPathName(); if ( m_origFile == "" )
return; ifstream inFile( m_origFile ); if( ! inFile )
MessageBox(_T("cannot open the infile ") ); string strLine; wstring wstrLine; m_showOrig = _T(""); while( getline( inFile, strLine ) ) {
wstrLine = Ansi2Unicode( strLine ); m_showOrig = m_showOrig + wstrLine.c_str () + _T("\r\r\n"); } UpdateData(FALSE); UpdateWindow(); inFile.close();
2 功能及特点
查找替换工具提供了 “查找”、 “匹配” 和 “替换” 3 种 功能。 “查找” 功能的界面如图 1 所示; “匹配” 功能的界面 如图 2 所示; “替换” 功能的界面如图 3 所示。 使用这个程序 时, 首先点击 “浏览” 按钮打开 “文件选择对话框”, 从中选 择需要处理的文本文件 (后 缀 名 为 txt), 用 户 选 择 之 后 , 该 文 本文件中的内容就会在界面左下方的编辑控件中显示出来; 然 后编辑正则表达式, 如果要使用 “替换” 功能, 还要在 “替 换” 命令按钮前面的编辑框中输入要替换的内容; 最后根据任 务需要点击 “查找”、 “匹配” 和 “替换” 3 个命令按钮之一, 程序就可以把符合条件的文本在界面右下方的编辑框中显示出 来, 并且保存处理后的文本到一个新的文件中, 这个新文件的 名称会在界面最下方的编辑框中显示出来。
设置为 “真”, “垂直滚动” 设置为 “真”, “多行” 设置为
“真”。 其他控件均使用默认设置。
3.3 编写调用函数代码
(1) 函 数 Ansi2Unicode; 功 能 是 把 ANSI 编 码 的 多 字 节 字
符串转化为 Unicode 编码的宽字符串:
wstring Ansi2Unicode(string astrsrc) { int nLength = ::MultiByteToWideChar ( CP_ACP, 0, astrsrc.c_str(), -1, NULL, 0); if(nLength <= 0) return wstring(L""); wchar_t *szbuffer = new wchar_t[nLength + 2]; ::MultiByteToWideChar (CP_ACP, 0, astrsrc.c_str (), -1, szbuffer, nLength); wstring strnew = szbuffer; delete [] szbuffer; return strnew; }
提示
编辑框 IDC_EDIT1 命令按钮 IDC_BUTTON2 浏览
m_origFile
显示用户所选择的文 件名 打开文件选择对话框, 选择文件
命令按钮 IDC_BUTTON3 编辑正则表达式:
提示
编辑框 IDC_EDIT2
m_ere
编辑和显示正则表达式
命令按钮 IDC_SEARCH 查找
查找符合条件的文本