65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.36/5 (16投票s)

2000年10月16日

2分钟阅读

viewsIcon

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 使事情变得更加容易。

© . All rights reserved.