在 C++ 程序中使用正则表达式






3.36/5 (16投票s)
2000年10月16日
2分钟阅读

207351
如何在 C++ 程序中使用 Microsoft 正则表达式对象
引言
正则表达式提供了一种方便的方式来指定复杂的字符串模式,用于搜索、替换或验证文本输入。由于它非常有用,很多人编写了自己的库。我发现的许多库都有错误,并且调试源代码需要花费大量时间。然而,实际上你不需要再寻找了,因为你的电脑里已经内置了一个免费的正则表达式解析器——微软编写的正则表达式解析器。
与其他实用程序一样,微软使用 COM 接口提供此功能。使用 oleview 工具很容易找到这个 COM 服务器对象,名为 Microsoft VBScript Regular Expressions 5.5。
一个问题是,这个 DLL 没有关联的类型库。幸运的是,这并不是什么大问题,因为我们有 IDL 定义。从 OleView 中,将 IDL 定义保存到文件中,并使用 MIDL 编译它,你将获得类型库。之后,我们可以在 C++ 程序中使用这个类型库。假设我们有一个名为 RegExp.tlb 的文件。
使用正则表达式
你可以在 MSDN 或 URL http://msdn.microsoft.com/scripting/default.htm?/scripting/vbscript/doc/vsobjregexp.htm 中找到所有文档。虽然它是为脚本编写的,但你可以仍然可以使用它们,借助 Visual C++ 6 中新添加的 #import 关键字。通常,你定义一个模式,然后你可以将该模式与输入字符串进行测试,或者执行以查看是否有任何匹配项。
为了演示其用法,我们编写了一个自定义 DDX 例程来验证对话框中控件的输入。函数原型如下所示
void WINAPI DDX_RegExp(CDataExchange* pDX, int nIDC, LPCTSTR lpszPattern, CString& value);
如果控件输入完全匹配指定的模式 (lpszPattern),则验证通过,否则将弹出一个消息框。
#import "RegExp.tlb" no_namespace ... void AFXAPI DDX_RegExp(CDataExchange* pDX, int nIDC, LPCTSTR lpszPattern, CString& value) { try { static IRegExpPtr regExp( __uuidof(RegExp) ); regExp->Pattern = _bstr_t(lpszPattern); HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC); if (pDX->m_bSaveAndValidate) { int nLen = ::GetWindowTextLength(hWndCtrl); ::GetWindowText(hWndCtrl, value.GetBufferSetLength(nLen),nLen+1); value.ReleaseBuffer(); //now we verify it if ( regExp->Test( (LPCTSTR)value) ) { IMatchCollectionPtr matches=regExp->Execute((LPCTSTR)value); if ( matches->Count== 1) { IMatchPtr match = matches->Item[0]; if ( match->FirstIndex==0 && match->Length == value.GetLength() ) { return; } } } CString strMsg = CString("The input does not exactly have the pattern ") + lpszPattern; pDX->m_pDlgWnd->MessageBox(strMsg); pDX->PrepareEditCtrl(nIDC); pDX->Fail(); } else { } } catch (_com_error& e) { AfxMessageBox( e.ErrorMessage() ); } }
在上面的代码中,我们首先使用 Test 方法来查看是否存在匹配项。如果存在,我们使用 Execute 方法来检索所有匹配项。应该只有一个匹配项。
定义好之后,我们可以在 MFC 应用程序中使用这个函数。请注意,你必须首先在应用程序中初始化 COM 库。以下将验证一个输入框,以查看它是否匹配电话号码格式
DDX_RegExp(pDX, IDC_INPUT, _T("\\d{3}-\\d{3}-\\d{4}"), m_strInput);
这样,你可以为更复杂的模式编写验证代码。COM 使事情变得更加容易。