现在的位置: 首页 > 综合 > 正文

VC6下正则greta库的测试和使用手记

2012年08月23日 ⁄ 综合 ⁄ 共 3795字 ⁄ 字号 评论关闭

文本字符串的处理、分析一直是写程序中不可避免的问题,长时间以来,自己对正则表达式这个纸老虎一直退避三舍。也许是懒的缘故吧,一般遇到字符串处理问题的时候,都是自己写个小程序完事,但工作效率实在是低下,做的多了就有点烦--都是重复性工作。昨天闲着没事,终于下决心看看正则了,很欣喜,收获还是不小的。

关于正则表达式的学习,推荐这篇文章,“正则表达式三十分钟入门”,我这么零基础的人,边看边练,两个小时确实是入门了,所以强烈推荐。其他关于正则的详细内容就不说了,不属于本文讨论的内容,下面言归正传。

学正则表达式,练习是少不了的,虽然工具不少,但为了以后自己写程序时方便,还是决定自己写一个。Google了一下,正则库还真是不少,像Boost、CAtlReg、Greta等,还有其他很多。粗粗看了一下,觉得Boost块头太大了,还得一步步编译啥的,懒人就放弃了,CAtlreg又好像不能在VC6下用,看看Greta就6个文件--着实很亲切,所以就它了。

网上关于Greta的文档不是很多,不知道是太简单了还是用的人太少,例子大多也是greta库文件里的示例,太简单,没有详细的匹配、替换、分割功能的用法。

本文测试的环境是VC6(sp6)MFC环境,步骤如下,

1)直接将greta六个源文件拷贝到工程目录下,为了方便,建了个greta目录;

 这里测试就直接用了源文件,其实还可以先把greta编译成库文件来使用,更推荐这种用法。

2)包含greta头文件;

#include <string>
#include "greta\regexpr2.h"//这一个就够了
using namespace std;
using namespace regex;//greta库的命名空间

3)在greta两个cpp文件中加上头文件"stdafx.h",否则会报错;

  另外,如果仍遇到11个左右的莫名其妙错误时,可以把MFC设置为静态链接模式,我刚开始时候就遇到了这个问题,搞了半天不知道什么原因,后来就改了静态选项;不过写本文时,本来想看看这个错误是什么,好给大家贴出来,把MFC改回共享链接又正常了...那些错误就是搞不出来(bt...)

4)环境设置好,下面就可以使用了;

  几个重要的对象:

     rpattern--正则模式及设置,主要就用它;

     match_results--匹配结果容器;

     subst_results--替换结果容器;

     split_results--分割结果容器;

  基本主要的就这几个了,具体用法,贴代码,大家自己看;

 

//////////////////////////////////

 if( nChar==VK_ESCAPE )
  CDialog::OnOK();
 else if( nChar==VK_F5 ) //匹配查找
 {
  UpdateData();
  m_strResult = "";
  match_results result;
  REGEX_FLAGS dw = GLOBAL | ALLBACKREFS;
  if( m_bCase ) dw |= NOCASE;
  if( m_bMulti ) dw |= MULTILINE;
  if( m_bSingle ) dw |= SINGLELINE;
  //
  double tmS = clock();
  //
  rpattern pat((LPCTSTR)m_strReg, dw);
  int iGroups = pat.cgroups();
  int nCount = 0;
  match_results::backref_type br = pat.match( (LPCTSTR)m_strSource, result );
  if( 0 )//遍历结果方式1,任选一种方式即可
  {
   match_results::backref_vector vec = result.all_backrefs();
   match_results::backref_vector::iterator iter;
   if( br.matched )
   {
    for( iter = vec.begin(); iter != vec.end(); iter++ )
    {
     nCount++;
     string str = (*iter).str();
     m_strResult += str.c_str();
     m_strResult += "\r\n---------------------------------------------\r\n";
    }
   }
  }
  if( 1 )//遍历结果方式2
  {
   if( br.matched )
   {
    for( int i=0;i<result.cbackrefs();i++ )
    {
     if( i%iGroups == 0 )
     {
      nCount++;
      m_strResult += result.backref(i).str().c_str();
      m_strResult += "\r\n---------------------------------------------\r\n";
     }
    }
   }
  }
  double tmE = clock();
  CString strTip;
  strTip.Format(_T("  运行时间 %.2fms, 共找到 %d个匹配;"), double(tmE-tmS), nCount);
  GetDlgItem(IDC_STATIC_TIP)->SetWindowText(strTip);
  //
  UpdateData(FALSE);
 }
 else if( nChar == VK_F6 )//替换
 {
  UpdateData();
  m_strResult = "";
  //
  REGEX_FLAGS dw = GLOBAL | ALLBACKREFS;
  if( m_bCase ) dw |= NOCASE;
  if( m_bMulti ) dw |= MULTILINE;
  if( m_bSingle ) dw |= SINGLELINE;
  double tmS = clock();
  //
  rpattern pat((LPCTSTR)m_strReg, (LPCTSTR)m_strSub, dw);
  subst_results subResult;
  //
  string str((LPCTSTR)m_strSource);
  int nCount = pat.substitute(str, subResult);
  m_strResult = str.c_str();
  //
  double tmE = clock();
  CString strTip;
  strTip.Format(_T("  运行时间 %.2fms, 共完成替换 %d处;"), double(tmE-tmS), nCount);
  GetDlgItem(IDC_STATIC_TIP)->SetWindowText(strTip);
  //
  UpdateData(FALSE);
 }
 else if( nChar == VK_F7 )//分割字符串
 {
  UpdateData();
  m_strResult = "";
  //
  REGEX_FLAGS dw = GLOBAL | ALLBACKREFS;
  if( m_bCase ) dw |= NOCASE;
  if( m_bMulti ) dw |= MULTILINE;
  if( m_bSingle ) dw |= SINGLELINE;
  double tmS = clock();
  //
  rpattern pat((LPCTSTR)m_strReg, dw);
  split_results splitResult;
  //
  string str((LPCTSTR)m_strSource);
  int nCount = pat.split(str, splitResult);
  for( int ni=0;ni<nCount;ni++ )
  {
   string strSplit = splitResult[ni];
   m_strResult += strSplit.c_str();
   m_strResult += "\r\n---------------------------------------------\r\n";
  }
  //
  double tmE = clock();
  CString strTip;
  strTip.Format(_T("  运行时间 %.2fms, 共找到 %d个匹配;"), double(tmE-tmS), nCount);
  GetDlgItem(IDC_STATIC_TIP)->SetWindowText(strTip);
  //
  UpdateData(FALSE);
 }

/////----------结束-----------////////

 该工程项目代码在这里下载,已经包含了greta2.6.4源码文件;

 以上为初步测试结果,可能在使用和介绍中有错误和不当之初,欢迎大家多交流探讨。

--------------------------------------

ppzhang ,2009-05-22, giszhang@gmail.com

 

抱歉!评论已关闭.