程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> VC6下正則greta庫的測試和使用手記

VC6下正則greta庫的測試和使用手記

編輯:關於VC++

文本字符串的處理、分析一直是寫程序中不可避免的問題,長時間以來,自己對正則表達式這個紙老虎一直退避三捨。也許是懶的緣故吧,一般遇到字符串處理問題的時候,都是自己寫個小程序完事,但工作效率實在是低下,做的多了就有點煩--都是重復性工作。昨天閒著沒事,終於下決心看看正則了,很欣喜,收獲還是不小的。

關於正則表達式的學習,推薦這篇文章,“正則表達式三十分鐘入門”,我這麼零基礎的人,邊看邊練,兩個小時確實是入門了,所以強烈推薦。其他關於正則的詳細內容就不說了,不屬於本文討論的內容,下面言歸正傳。

學正則表達式,練習是少不了的,雖然工具不少,但為了以後自己寫程序時方便,還是決定自己寫一個。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);
 }
/////----------結束-----------////////

以上為初步測試結果,可能在使用和介紹中有錯誤和不當之初,歡迎大家多交流探討。

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved