一、VS2008(Sp1)环境使用CAtlRegExp类需要额外下载ATL Server,(因为开源代码,没集成在VS2008里了) http://atlserver.codeplex.com/
最后在需要的地方添加UpdateData()函数(它会调用DoDataExchange)
二、下载后解压,如F:\CPP\ATL_Server_Source_and_Headers_9_0_70425_Alpha
然后设置路径:【工具】->【选项】->【项目和解决方案】->【VC++目录】,在【包含文件】添加目录 F:\CPP\ATL_Server_Source_and_Headers_9_0_70425_Alpha\include
三、使用方法
(1)、h文件中
包含头文件
#include <atlrx.h>
变量
CString m_szPixels;
float m_nPixels;
定义函数
static CString REError2String(REParseError status);
(2)、CPP实现文件
主要代码添加在DoDataExchange();
void CPageMeasument::DoDataExchange(CDataExchange* pDX)
{
CPropertyPage::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_szPixels);
DDX_Text(pDX, IDC_EDIT2, m_nDefaultZoomFactor);
DDX_Control(pDX, IDC_COMBO_UNITS, m_cboUnits);
CString szErr(_T("Parser Error:"));
if ( pDX->m_bSaveAndValidate ) {
// create regular expression content
CAtlRegExp<> regex;
REParseError status = regex.Parse(L"^{[-+]?\\d+}{\\.}?{\\d*}{[eE][-+]?\\d+}?$");
if (REPARSE_ERROR_OK != status) {
// invalid pattern, show error
szErr += REError2String(status);
} else {
// valid regex pattern, now try to match the content
CAtlREMatchContext<> mc;
if (!regex.Match(m_szPixels, &mc)) {
// content not match
m_szPixels = _T("");
m_nPixels = -1;
} else {
// content match, show match-group like this
// for (UINT nGroupIndex = 0; nGroupIndex < mc.m_uNumGroups; ++nGroupIndex)
// {
// const CAtlREMatchContext<>::RECHAR* szStart = 0;
// const CAtlREMatchContext<>::RECHAR* szEnd = 0;
// mc.GetMatch(nGroupIndex, &szStart, &szEnd);
// ptrdiff_t nLength = szEnd - szStart;
// CString text(szStart, nLength);
// //text是各个拆开后的字符串,可以打印出来
// }
m_nPixels = (float)_tstof((const wchar_t*)m_szPixels.GetBuffer(0));
}
}
//print error message "szErr" here
//AfxMessageBox(szErr);
}
}
定义错误函数
CString CPageMeasument::REError2String(REParseError status)
{
switch (status) {
case REPARSE_ERROR_OK: return TEXT("No error occurred");
case REPARSE_ERROR_OUTOFMEMORY: return TEXT("Out of memory");
case REPARSE_ERROR_BRACE_EXPECTED: return TEXT("A closing brace was expected");
case REPARSE_ERROR_PAREN_EXPECTED: return TEXT("A closing parenthesis was expected");
case REPARSE_ERROR_BRACKET_EXPECTED: return TEXT("A closing bracket was expected");
case REPARSE_ERROR_UNEXPECTED: return TEXT("An unspecified fatal error occurred");
case REPARSE_ERROR_EMPTY_RANGE: return TEXT("A range expression was empty");
case REPARSE_ERROR_INVALID_GROUP: return TEXT("A back reference was made to a group that did not exist");
case REPARSE_ERROR_INVALID_RANGE: return TEXT("An invalid range was specified");
case REPARSE_ERROR_EMPTY_REPEATOP: return TEXT("A repeat operator (* or +) was applied to an expression that could be empty");
case REPARSE_ERROR_INVALID_INPUT: return TEXT("The input string was invalid");
default: return TEXT("Unknown error");
}
}
void CPageMeasument::OnOK()
{
UpdateData(TRUE);
if ((m_nPixels <= 0) && (BST_CHECKED==((CButton*)GetDlgItem(IDC_CHECK1))->GetCheck()))
{
CRect rect;
GetDlgItem(IDC_EDIT1)->GetWindowRect(&rect);
CPoint pt = rect.CenterPoint(); pt.x = rect.right-15;
m_tooltip.SetDirection(PPTOOLTIP_LEFTEDGE_TOP);
m_tooltip.ShowHelpTooltip(&pt, _T("<center><h2>Check input</h2><br><hr color=blue></center><br>You maybe enter a illegal values"));
return ;
}
if ((m_cboUnits.GetCurSel() < 0) && (BST_CHECKED==((CButton*)GetDlgItem(IDC_CHECK1))->GetCheck()) )
{
CRect rect;
GetDlgItem(IDC_COMBO_UNITS)->GetWindowRect(&rect);
CPoint pt = rect.CenterPoint(); pt.x = rect.right-15;
m_tooltip.SetDirection(PPTOOLTIP_LEFTEDGE_TOP);
m_tooltip.ShowHelpTooltip(&pt, _T("<center><h2>Check input</h2><br><hr color=blue></center><br>Select a units"));
return ;
}
CPropertyPage::OnOK();
}
四、说明
这里检测浮点数的正则表达式式子是 ^{[-+]?\\d+}{\\.}?{\\d*}{[eE][-+]?\\d+}?$ ,本来语法是 ^([-+]?\d+)(\.)?(\d*)([eE][-+]?\d+)?$
使用CAtlRegExp类需要将()改成{}才行,列外C++代码里面\要用转义字符 \\ 表示,所以\d 写成\\d
L"^{[-+]?\\d+}{\\.}?{\\d*}{[eE][-+]?\\d+}?$" 表示是Unicode字符串,前面加个L 修饰
这个正则表达式表示的浮点数可以是:
-.2 -0.2 +0 +0. +.2 1.23 -1.23 +1.23e-3 +1.23E+3 -1.23e-5 123 123. 123.e-3
等等各种合法浮点数。。
列外在这个网站http://regexlib.com/ 可以搜到很多现成的一些正则表达式。。。。。。。。。
五、结果,检测非法输入
六、为什么要正则表达式来检测输入的字符串,而不直接给Edit定义一个float变量,因为第一为了美观,UpdataDate()时如果输入非法会弹出一些很丑的对话框,而且输入也不怎么好。。。。