深入淺出C/C++中的正則表達式庫


寫在前面: 本文是面向有正則表達式基礎的讀者朋友的,如果你還不知道正則表達式是什么,請先到這里學習一下 ;-) :http://en.wikipedia.org/wiki/Regular_expression

正則表達式(Regular Expressions),又被稱為regex或regexp,是一種十分簡便、靈活的文本處理工具。它可以用來精確地找出某文本中匹配某種指定規則的內容。在Linux下,grep, sed, awk等工具都支持正則表達式,這些工具的存在,為我們日常的文本處理帶來了極大的便利。但是,有時候,我們自己寫的程序中也需要用到正則表達式來處理一些文本,這時候就需要一些正則表達式庫的支持了。由於我本人是用C/C++做為主要開發語言的,所以,在本文以及接下來的幾篇文章中,我將介紹幾個常用的C/C++的正則表達式的庫,通過我的介紹,以及對具體的使用進行舉例,希望能夠給讀者朋友在C/C++程序中使用正則表達式時有點幫助,這將是我莫大的榮幸。

當前,據我所知,在C/C++中常用的正則表達式庫有GNU Regex Library, Boost.Regex, PCRE, PCRE++。這四個庫中,后面兩個是有關系,其它都是各自己獨立的,是不同的實現。因此我會分三次,來一一對這四個庫進行介紹。今天首先介紹一下GNU Regex Library。

1. 什么是GNU正則表達式庫(GNU Regex Library) ?
GNU正則表達式庫是glibc(GNU C Library)的一部分,它提供與POSIX標准兼容的正則表達式匹配的接口。
這里是其主頁:http://www.gnu.org/s/libc/manual/html_node/Regular-Expressions.html
下載該庫點這里:gnuregex0_13

2. GNU Regex Library所提供的接口
(1)regcomp:

    int regcomp(regex_t *preg, const char *pattern, int cflags)  
    功能:將要進行匹配的正則表達式pattern進行編譯,做匹配前的准備工作  
    參數: preg, 輸出參數,用來保存編譯后的正則表達式結果  
          pattern, 輸入參數,傳入要進行編譯的正則表達式的字符串  
          cflags, 輸入參數,用來指定正則表達式匹配過程中的一些選項  
    返回值:編譯成功返回0,失敗返回非0的錯誤碼  

(2)regexec:

int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags)  
功能:用來檢測字符串string是否匹配正則表達式preg  
參數: preg, 輸入參數,在(1)regcomp中編譯好的正則表達式規則  
      string, 輸入參數,用來被匹配的字符串  
      nmatch, 輸入參數,用來指定pmatch參數所對應的數組的長度  
      pmatch, 輸出參數,用來輸出在string中匹配preg的具體位置  
      eflag, 輸入參數,用來指定正則表達式匹配過程中的一些選項  
返回值: 如果string匹配preg所指定的規則,則返回0, 否則返回非0  

3)regerror:

 size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)  
功能:用來把在regcompt和regexec中產生的錯誤碼轉化成字符串形式的錯誤信息  
參數: errcode, 輸入參數,在regcomp或regexec調用中返回的錯誤碼  
      preg, 輸入參數,與錯誤碼所對應的編譯過的正則表達式結構  
      errbuf, 輸出參數,用來返回錯誤信息的buffer,如果buffer不夠所需大小,錯誤信息將被截斷  
      errbuf_size, 輸入參數,返回錯誤信息的buffer的大小   
返回值: 如果errbuf_size為0,那么regerror返回錯誤信息所需要的buffer的大小

(4)regfree:

    void regfree (regex_t *preg)  
    功能: 用來釋放由regcomp編譯時生成的preg結構所占用的內存  
    參數: preg, 輸入參數,由regcomp編譯時生成的正則表達的結構指針  
    返回值: 無  

3. 使用GNU Regex Library的一些注意事項
(1)regcomp與regfree必須配對使用,要不然會造成內存泄漏(類比malloc/free, new/delete)
(2)regex_t結構:把字符串形式的正則表達式編譯成regex_t這樣的一個結構,方便后續的匹配工作
(3)regmatch_t結構:用來表示正則表達式中字符串中匹配的位置的結構,用起始位置的偏移量來表示的
(4)flags:用來配置匹配過程中的一些選項, 指定如何匹配,具體參見:http://www.opengroup.org/onlinepubs/007908799/xsh/regcomp.html
(5)使用該庫需要包含的頭文件:sys/types.h和regex .h



4. GNU Regex Library使用舉例

[cpp] 

<span style=></span><pre = name=>#include <sys /types.h>  

  •   
  • #include <stdio .h> int argc,  ** argv)  
  • {  
  •  (argc != 3)  
  •     {  
  •  1;  
  •   * pRegexStr = argv[1];  
  •       * pText = argv[2];  
  •  nErrCode = 0;  
  •      szErrMsg[1024] = {0};  
  •  unErrMsgLen = 0;  
  •    
  •  ((nErrCode = regcomp(&oRegex, pRegexStr, 0)) == 0)  
  •     {  
  •  ((nErrCode = regexec(&oRegex, pText, 0, NULL, 0)) == 0)  
  •         {  
  •  0;  
  •         }  
  • (szErrMsg));  
  •     unErrMsgLen = unErrMsgLen < (szErrMsg) ? unErrMsgLen : (szErrMsg) - 1;  
  • ;  
  •     printf(  1;  
  • }  
  • </pre>  

程序測試

[cpp] 

wuzesheng@wuzesheng-ubuntu:~/Program$ gcc TestRegex.c -o Regex  

  • wuzesheng@wuzesheng-ubuntu:~/Program$ ./Regex    
  •    
  • //www.taobao.com matches http:\/\/www\..*\.com  

以上即是關於GNU Regex Library的全部內容。如果讀書者朋友有什么看法可以在下面給我留言。接下來幾天,我會陸續介紹前面提到的其它幾個庫,今天先到這里。

 

寫在前面:本文是《深入淺出C/C++中的正則表達式庫》系列的第二篇,如果對本文感興趣,相信你也會對《深入淺出C/C++中的正則表達式庫——GNU Regex Library》感興趣。本文主要介紹Boost中的正則表達式庫,通過介紹其基本內容與相關接口,希望能夠教讀者朋友學會如何使用該庫。

1. 什么是Boost.Regex? 
Boost是C++中僅次於STL的一套庫,它的功能比STL更加全面。這里是Boost的主頁,想了解Boost的朋友可以看一下:http://www.boost.org/doc/libs/1_37_0/libs/regex/doc/html/index.html。需要說明的一點是,Boost目前還不是C++標准庫的一部分,因此如果要使用Boost中的庫,需要自己安裝一下。

Boost.Regex是Boost中的正則表達式庫,它是由John Maddock提供的,它的全部文檔在這里:http://www.boost.org/doc/libs/1_37_0/libs/regex/doc/html/index.html

2. Boost.Regex的編譯
最新的Boost庫是1.42.0,在使用Boost.Regex之前,需要先下載Boost庫,可以通過下面兩種方式下載:
(1)Http下載,下載地址是http://sourceforge.net/projects/boost/files/boost/1.42.0/
(2)用svn客戶端來下載,地址是:http://svn.boost.org/svn/boost/trunk/
我個人比較推薦使用svn客戶端來下載,這樣的話,如果要更新直接svn update一下,就不用再去重新下載了。

下載好了Boost庫,下面開始編譯, 本文中我以Linux平台為例進行說明,其它平台的編譯方法參見上面提到的文檔。下面是具體的步驟:(假設下載完后的,代碼解壓在了BOOST_ROOT目錄)
(1)進入到BOOST_ROOT/libs/regex/build目錄
(2)如果要使用靜態庫,請執行make -fgcc.mak
(3)如果要使用靜態庫,請執行make -fgcc-shared.mak
執行完上面三步后的,在BOOST_ROOT/libs/regex/build/下會生成一個gcc目錄 ,進入該目錄 ,可以看到生成了下面四個文件:
(1)libboost_regex-gcc-1_42.a , 這是release版的靜態庫
(2)libboost_regex-gcc-1_42.so, 這是release版的動態庫(共享庫)
(3)libboost_regex-gcc-d-1_42.a, 這是debug版的靜態庫
(4)libboost_regex-gcc-d-1_42.so, 這里debug版的動態庫(共享庫)
編譯好之后的,就可以開始使用了。這里提供一個我編譯好的版本,如果讀者朋友不想自己編譯,可以直接從我這里下載使用,下載完記得校驗一下MD5: b6e0d805ea22ba08cb230ca98a517953。
點此下載:libboost_regex.tar.gz

3. Boost Regex Libray類和接口介紹
(1)basic_regex
basic_regex是一個模板類,它封裝了正則表達式的解析和編譯,它是Boost.Regex中用來表示正則表達式的對象類型。Boost.Regex定義了兩種標准類型,一種是基於單字節字符的regex,另一種是基於寬字符的wregex
關於basic_regex提供的接口,和STL中basic_string所提供的十分類似,具體可以參考:
http://www.boost.org/doc/libs/1_37_0/libs/regex/doc/html/boost_regex/ref/basic_regex.html

(2)match_results
match_results是用來表示所有匹配指定正則表達式的字符串的集合的對象類型。Boost.Regex提供了四種標准類型的定義:C單字節字符類型的cmatch, C寬字符類型的wcmatch, C++單字節字符類型smatch, C++寬字符類型wsmatch。match_results所提供的接口參見:
http://www.boost.org/doc/libs/1_37_0/libs/regex/doc/html/boost_regex/ref/match_results.html

(3)sub_match
sub_match是用來表示匹配指定正則表達式的字符串的對象類型。match_results就是由sub_match組成的集合類型。
關於sub_match類型,有下面三點需要注意的:
a. sub_match類型的對象只能通過對match_results類型的對象取下標獲取
b. sub_match類型的對象可以和std:basic_string或const char*的字符串進行比較
c. sub_match類型的對象可以和std::basic_string或const char*的字符串相加,生成新的std::basic_string類型的字符串
sub_match所提供的接口請參考:
http://www.boost.org/doc/libs/1_37_0/libs/regex/doc/html/boost_regex/ref/sub_match.html

(4)reg_match, reg_search和reg_replace
reg_match, reg_search和reg_replace都是Boost.Regex所提供的具體進行正則匹配的算法接口。
reg_match用來判定整個字符串是否匹配指定的的正則表達式, 具體定義參見:
http://www.boost.org/doc/libs/1_37_0/libs/regex/doc/html/boost_regex/ref/regex_match.html
reg_search用來判定字符串的某一部分是否匹配指定的正則表達式, 具體定義參見:
http://www.boost.org/doc/libs/1_37_0/libs/regex/doc/html/boost_regex/ref/regex_search.html
reg_replace用來把字符串中匹配指定正則表達式的部分替換為指定內容輸出,對於不匹配的部分原樣輸出, 具體定義參見:
http://www.boost.org/doc/libs/1_37_0/libs/regex/doc/html/boost_regex/ref/regex_replace.html

4. Boost Regex Libray使用注意事項
(1)在使用之前你需要把Boost的安裝目錄加入到系統的Path中(當然也可以在編譯時直接指定)
(2)需要包含的頭文件 boost/regex.hpp
(3)需要依賴的庫:下載2中編譯好的libboost.tar.gz,取其中任意一個即可,具體如何使用動態/靜態庫,請自己查閱相關資料
(4)Boost.Regex還提供對Unicode類型的支持,具體細節參加上面提到的文檔,我這里不做介紹

5. Boost.Regex使用舉例
下面是Boost.Regex使用的一個簡單的例子:

[cpp] 

<span style=></span> <pre = name=>#include <string>  

  •   
  • #include "boost/regex.hpp" int argc,  ** argv)  
  •  (argc != 4)  
  •  1;  
  •  (atoi(argv[1]))  
  •  0:  
  • (boost::regex_match(strStr, oResults, oRegex))  
  •             {     
  • ;  
  •             }     
  •   
  •             {     
  • ;  
  •             }     
  • ;  
  •          1:  
  • (boost::regex_search(strStr, oResults, oRegex))  
  •             {  
  • ;  
  •             }  
  •   
  •             {  
  • ;  
  •             }  
  • ;  
  •          2:  
  • );  
  •             std::cout <<  << strRes << ;  
  • ;  
  •         :  
  • ;  
  •             ;  
  • </pre>  

 

 

下面是程序運行的結果:

wuzesheng@wuzesheng-ubuntu:~/Program$ !g++  

  • g++ -I./boost_1_42_0 BoostRegex.cpp -L ./boost_1_42_0/libs/regex/build/gcc/ -lboost_regex-gcc-1_42 -o BoostRegex  
  •    
  • http:  
  •    
  • http:  
  •    
  • strRes=$jfj  

以上即是Boost.Regex的主要的內容以及具體使用的一些情況。這里我需要說明一下,由於Boost.Regex所提供的像basic_regex, match_results, sub_match這些類型,它們的封裝與C++中string等其它stl容器的封裝很相似,因此使用過程中可以做聯想類比,以加深理解。另外,像regex_match, regex_search, regex_replace這些算法都是模板函數,而且都有多個重載版本,在使用的時候,注意選擇適合自己的應用場景的版本。

寫在前面:本文是《深入淺出C/C++中的正則表達式庫》系列的第三篇,本文的主要內容是介紹PCRE和PCRE++,因為它們兩個是很有淵源的,所以放在一起講。

1. 什么是PCRE? 什么是PCRE++?PCRE,全稱是Perl Compatible Regular Expressions。從名字我們可以看出PCRE庫是與Perl中正則表達式相兼容的一個正則表達式庫。PCRE是免費開源的庫,它是由C語言實現的,這里是它的官方主頁:http://www.pcre.org/,感興趣的朋友可以在這里了解更多的內容。要得到PCRE庫,可以從這里下載:http://sourceforge.net/projects/pcre/files/

PCRE++是一個對PCRE庫的C++封裝,它提供了更加方便、易用的C++接口。這里是它的官方主頁:http://www.daemon.de/PCRE,感興趣的朋友可以在這里了解更多的內容。要得到PCRE++庫,可以從這里下載:http://www.daemon.de/PcreDownload2. PCRE接口介紹(1). pcre_compile

[cpp] 

pcre <span style=>*</span>pcre_compile<span style=>(</span><span style=></span> <span style=></span> <span style=>*</span>pattern, <span style=></span> options,<span style=></span> <span style=></span> <span style=>**</span>errptr, <span style=></span> <span style=>*</span>erroffset, <span style=></span> <span style=>unsigned</span> <span style=></span> <span style=>*</span>tableptr<span style=>)</span><span style=>;</span>  

  • 功能:編譯指定的正則表達式  
  • >NULL</span>, 使用缺省的字符表  
  • 返回值:被編譯好的正則表達式的pcre內部表示結構  

(2). pcre_exec

<strong></strong><pre = name=> pcre_exec( pcre *code,  pcre_extra *extra,   *subject,  length,  startoffset,  options,  *ovector,  ovecsize);  

  • 功能:用來檢查某個字符串是否與指定的正則表達式匹配  
  • </pre>  

3. PCRE++接口介紹 
PCRE++把PCRE庫封裝成了兩個類,一個是RE_Options, 用來指定匹配選項,一個是RE,用來提供匹配相關的接口。RE_options類在這里我就不介紹了,我主要介紹一下RE類:
(1)RE的構造函數傳入正則表達式,並在構造函數中調用Init函數,將該正則表達進行編譯
(2)RE的pattern()成員用來得到初始傳入的正則表達式字符串
(3)RE的error()成員用來得到匹配過程中的出錯信息
(4)RE的FullMatch()成員用來判斷某字符串整體是否匹配指定正則表達式
(5)RE的PartialMatch()成員用來判斷某字符串的部分是否匹配指定正則表達式

4. PCRE/PCRE++使用注意事項
(1)使用pcre請包含pcre.h頭文件
(2)使用pcre_compile, pcre_exec后,記得調用pcre_free釋放內存,以免造成內存泄露
(3)使用pcre編譯的時候需要依賴libpcre.a
(4)使用pcre++請包含pcrecpp.h頭文件
(5)使用pcre++,RE類的析構函數會自動釋放相關內存,因此不用擔心內存泄露
(6)使用pcre++編譯的時候需要依賴libpcrecpp.a
(7)使用pcrecpp要使用pcrecpp命名空間

5. PCRE使用舉例
下面是例程:

<span style=></span><pre = name=>#include <pcre .h>  

  •   
  • #include <string .h> int argc,  ** argv)  
  • {  
  •  (argc != 3)  
  •     {     
  •  1;  
  •   * pPattern = argv[1];  
  •       * pText = argv[2];  
  •   * pErrMsg = NULL;  
  •     pcre * pPcre = NULL;  
  •  nOffset = -1;   
  •    
  •  (NULL == (pPcre = pcre_compile(pPattern, 0, &pErrMsg, &nOffset, NULL)))  
  •     {     
  •  1;  
  •   
  •  (pcre_exec(pPcre, NULL, pText, strlen(pText), 0, 0, NULL, 0) < 0)  
  •   
  • </pre>  

下面是運行結果:

wuzesheng@wuzesheng-ubuntu:~/Program$ !g++  

  • g++ -lpcre TestPcre.cpp -o pcre  
  •    
  • http:  
  •    
  • http:  

6. PCRE++使用舉例
下面是例程:

<span style=></span><pre = name=>#include <iostream>  

  •   
  • int argc,  ** argv)  
  •  (argc != 3)  
  •  1;  
  •     }     
  •  (oPattern.FullMatch(argv[2]))  
  •     {     
  • ;  
  •     }     
  •   (oPattern.PartialMatch(argv[2]))  
  •     {     
  • ;  
  •     }     
  •   
  •     {     
  • ;  
  •     }     
  • }</pre><br>  

下面是運行結果:

wuzesheng@wuzesheng-ubuntu:~/Program$ g++ TestPcreCpp.cpp -lpcrecpp -o pcrecpp  

  • wuzesheng@wuzesheng-ubuntu:~/Program$ ./pcrecpp   
  •    
  • //www.qq.com fully matches http:\/\/.*\.qq\.com    
  • //www.qq.comiii partially matches http:\/\/.*\.qq\.com    
  • //www.qqq.comiii dose not match http:\/\/.*\.qq\.com  


以上即是關於PCRE和PCRE++庫介紹的全部內容,由於內容比較多,我只介紹了一些關鍵的接口及其用法,如果讀者朋友想更加深入的了解其它的接口,可以參考我上面提到的官方網站,另外linux下的manual也是很好的參考資料。在shell下執行man pcre和man pcrecpp便可得到很詳細的資料。


轉自:

http://www.wuzesheng.com/?p=929

http://www.wuzesheng.com/?p=965

http://www.wuzesheng.com/?p=994


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM