正则表达式最实用的一个地方是验证用户输入。它可以轻松验证邮编、电话号码、信用卡号码——以及现实世界中各种类型的信息。一个正则表达式可以替换成打甚至上百行过程代码。Unix和Web编程语言如Perl从一开始就有正则表达式,但在Windows世界或MFC,从来都是使用第三方库,一直到net 框架才结束这个局面。因此现在 .NET 提供一个完整的正则表达式库,为什么不在MFC应用程序中使用它呢?利用 RegexWrap 库,你甚至都不需要托管扩展或 /clr。
MFC 已经具备一种称为“对话框数据交换”(Dialog Data Exchange即 DDX)以及“对话框数据验证”(Dialog Data Validation,即 DDV)的机制来验证对话框输入。从技术上讲,DDX 只是在屏幕和你的对话框对象之间传输数据,而 DDV 才验证数据。当你从对话框的 OnOK 处理例程中调用 UpdateData 时 DDX 才开始工作。
// user pressed OK:
void CMyDialog::OnOK() {
UpdateData(TRUE); // 获得对话框数据
...
} |
UpdateData 是一个虚拟 CWnd 函数,你可以在自己的对话框中重写这个函数。其布尔型(Boolean)参数告知是将信息拷贝到屏幕还是相反从屏幕拷贝信息。(你可以在 OnInitDialog 中调用 UpdateData(FALSE)以便初始化对话框)。默认的 CWnd 实现创建一个 CDataExchange 对象并将它传递到另一个虚拟函数,DoDataExchange,你得重写这个函数去调用专门的 DDX 函数来为单独的数据成员传递数据:
void CMyDialog::DoDataExchange(CDataExchange* pDX) {
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_NAME, m_name);
DDX_Text(pDX, IDC_AGE, m_age);
...
// etc.
} |
这里 IDC_NAME 和 IDC_AGE 是编辑控制的 IDs,m_name 和 m_age 分别是 CString 和 int 数据成员。DDX_Text 将用户输入的 Name 和 Age 拷贝到 m_name 和 m_age(用一个重载顺便将 Age 转变成 int)。DDX 函数知道走哪条路,因为当从屏幕拷贝到对话框时,CDataExchange::m_bSaveAndValidate 为 TRUE,反之则为 FALSE。MFC 为各种数据和控制类型加载 DDX 函数。例如,DDX_Text 至少有一些重载函数用来将输入文本拷贝和转换成不同的类型,如
CString、int、double、COleCurrency 等等。DDX_Check 用来将复选框的状态转换成整型值,DDX_Radio 则对单选按钮做同样的事情。
DDX 函数传输数据;DDV 函数则验证它。例如,为了限制用户名称为 35个字符,你可以这样做:
// in CMyDialog::DoDataExchange
DDX_Text(pDX, IDC_NAME, m_sName); // 获得/设置值
DDV_MaxChars(pDX, m_sName, 35); // 验证 |
为了限定你的用户年龄为 1-120之间的一个整数,你可以这样写:
// m_age is int
DDX_Text(pDX, IDC_AGE, m_age);
DDV_MinMaxInt(pDX, m_age, 1, 120); |
虽然 DDX 工作表现得很好,DDV 是不免有点老土。MFC 在有效性验证方面所能做到的很有限。你可以在文本域中限制数字字符,不同类型的最小/最大约束。最小/最大是不错,但如果你想验证邮编或电话号码怎么办?MFC 对此无能为力。你不得不编写自己的 DDV 函数。当我第一次用正则表达式实现有效性验证时,我只要写一个函数即可,就像这样:
void DDV_Regex(CDataExchange* pDX, CString& val,
LPCTSTR pszRegex)
{
if (pDX->m_bSaveAndValidate) {
CMRegex r(pszRegex);
if (!r.Match(val).Success()) {
pDX->Fail(); // throws exception
}
}
} |
这使你很容易象下面这样用正则表达式验证输入:
// in CMyDialog::DoDataExchange
DDX_Text(pDX, IDC_ZIP, m_zip);
DDV_Regex(pDX, m_zip,_T("^\\d{5}(-\\d{4})?$")); |
好酷啊,仅用四行代码就搞掂。(当然,那要假设你有 RegexWrap——否则你得使用托管扩展直接调用框架 Regex 类。)DDV_Regex 在 MFC 的 DDX/DDV 方案中工作表现很完美,但是当我开始添加更多的域时,我马上发现一些 DDX/DDV 的主要缺点,其一,如果域输入无效,则每个 DDV 函数都显示一个出错消息框并丢出异常,那么要是有五个无效域,用户就会看到五个消息框——真实糟透了!此外,在对 DDV 的调用中,我不想将正则表达式写死在代码中。但我拒绝 DDX/DDV 的主要理由是它太程序化。为了验证新的域,你不得不添加另外的数据成员以及在
DoDataExchange 加更多的代码,不久这个函数便膨胀臃肿,就像下面这样:
DDX_Text(pDX, IDC_FOO,...);
DDV_Mumble(pDX, ...)
DDX_Text(pDX, IDC_BAR,...);
DDV_Bletch(...)
... // etc for 14 lines |
为什么我非得要墨守成规编写过程指令来描述固有的验证规则呢?我的五条编程最高准则之一是:拒斥程序化代码。另一个是:一个表格胜过一千行代码。你肯定猜到我要干什么了。最终,我编写自己的对话框验证系统,一个基于规则的、表格
驱动的验证系统。它依靠在 DDX 的最上层,但废掉了 DDV 并有好得多的用户接口。当然,它还易于使用,借助正则表达式进行验证。所有细节都封装在一个类中,CRegexForm,你可以在任何
MFC 对话框中使用这个类。
Figure 1 TestForm 里的工具提示
|
分享到:
相关推荐
VC、VC++,MFC 正则表达式类库
我想利用本月的专栏描述一个有趣...RegexForm 是一个基于正则表达式的MFC窗体有效性验证系统。为了实现这个程序,我首先实现了 RegexWrap。但因为许多细节与正则表达式本身无关,所以感觉在这里描述 RegexForm 更好些。
基于MFC对话框写的一个利用正则表达式对密码的合法性进行验证的demo。
VC++ MFC 文本分析 正则表达式编程小例
微软及自己的正则表达式的使用,跟主流的规则有点不太一样,自己找了很多资料,写了这个表达式,由于资料很少,所以这个还是有点缺陷,但是也够自己用的了
为了写正则表达式方便,分别用C++版本(MFC+libcurl+boost)以及python(re+wxWidget库)版本两个解析器,因为这两种解析器对于正则解析稍微有区别,例如python对于范围默认为最大,boost就默认为最小。版本提供了网页...
vc++6/MFC中使用boost示例,利用正则表达式分解字符串,替换文本,批量替换等,
为了写正则表达式方便,分别用C++版本(MFC+libcurl+boost)以及python(re+wxWidget库)版本两个解析器,因为这两种解析器对于正则解析稍微有区别,例如python对于范围默认为最大,boost就默认为最小。版本提供了网页...
MAC地址合法性检测(C,C++, JAVA实现)
已编译好的微软Greta 2.6.4 正则表达式库。 里面有5个文件(4个h,1个lib) 下载来直接放到要使用正则的项目里就行了。 #include #include "regexpr2.h" using namespace std; using namespace regex; #pragma ...
使用本类无需考虑ascll与unicode编码!非常简单! 使用方法: CmyRegex re(正则表达式); if(re.ftmatch(匹配字符串)) { 成功 } 类自带了汉字匹配、字母匹配、邮箱匹配等 详细请参考附件
内容索引:VC/C++源码,字符处理,有穷自动机,正则表达式 想研究透彻正则表达式,必须知道有穷自动机的原理,这个源码可以给你一个很好的示例参考。编译后程序会生成一个可执行文件,运行这个文件出来一个DOS窗口,...
vc工程编译会生成占用大量空间的中间文件,写这个小程序的初衷就是删除下面vc自动生成的,留下有用的源代码好打包,当然你也可以用作它用. ...取消掉了大的MFC90.dll,省得每次都要装那个8M多的运行环境
运用MFC 编写的表达式运算 采用计算器形式实现
基于MFC的计算器,能够完成各种功能的计算,
内容索引:VC/C++源码,字符处理,正则表达式 一个完美支持中文且语法完善的自制正则表达式库,这可能是第一个大陆程序员写的开源正则表达式库,原始作者 : lanzhengpeng(兰征鹏),作者放弃除著作署名权之外的任何权益...
基于MFC的一个用了计算表达式的计算器,例如可计算表达式 300-((4*34-5)/4+4) 的值,里面是一个完整的工程,代码后面都有足够详细的注释
呵呵,数据结构课程设计要求的,用了两个栈,一个放运算符,一个放操作数。 环境:VS.NET 2002
本人自己编写的一个简单文本编辑器,还有很多不完善的地方
项目中常用的正则表达式源代码总结,针对输入框内所输入的数值有效性检查,源代码,直接可用!