正規表達式(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标準相容的正規表達式比對的接口。
2. GNU Regex Library所提供的接口
int regcomp(regex_t *preg, const char *pattern, int cflags)
功能:将要進行比對的正規表達式pattern進行編譯,做比對前的準備工作
參數: preg, 輸出參數,用來儲存編譯後的正規表達式結果
pattern, 輸入參數,傳入要進行編譯的正規表達式的字元串
cflags, 輸入參數,用來指定正規表達式比對過程中的一些選項
傳回值:編譯成功傳回0,失敗傳回非0的錯誤碼
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
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的大小
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結構:用來表示正規表達式中字元串中比對的位置的結構,用起始位置的偏移量來表示的
(5)使用該庫需要包含的頭檔案:sys/types.h和regex .h
4. GNU Regex Library使用舉例
#include <sys /types.h>
#include <regex .h>
#include <stdio .h>
int main(int argc, char ** argv)
{
if (argc != 3)
{
printf("Usage: %s RegexString Text\n", argv[0]);
return 1;
}
const char * pRegexStr = argv[1];
const char * pText = argv[2];
regex_t oRegex;
int nErrCode = 0;
char szErrMsg[1024] = {0};
size_t unErrMsgLen = 0;
if ((nErrCode = regcomp(&oRegex, pRegexStr, 0)) == 0)
if ((nErrCode = regexec(&oRegex, pText, 0, NULL, 0)) == 0)
{
printf("%s matches %s\n", pText, pRegexStr);
regfree(&oRegex);
return 0;
}
unErrMsgLen = regerror(nErrCode, &oRegex, szErrMsg, sizeof(szErrMsg));
unErrMsgLen = unErrMsgLen < sizeof(szErrMsg) ? unErrMsgLen : sizeof(szErrMsg) - 1;
szErrMsg[unErrMsgLen] = '\0';
printf("ErrMsg: %s\n", szErrMsg);
regfree(&oRegex);
return 1;
}
程式測試:
wuzesheng@wuzesheng-ubuntu:~/Program$ gcc TestRegex.c -o Regex
wuzesheng@wuzesheng-ubuntu:~/Program$ ./Regex "http:\/\/www\..*\.com" "https://www.taobao.com"
ErrMsg: No match
wuzesheng@wuzesheng-ubuntu:~/Program$ ./Regex "http:\/\/www\..*\.com" "http://www.taobao.com"
http://www.taobao.com matches http:\/\/www\..*\.com
以上即是關于GNU Regex Library的全部内容。如果讀書者朋友有什麼看法可以在下面給我留言。接下來幾天,我會陸續介紹前面提到的其它幾個庫,今天先到這裡。
本文轉自nxlhero 51CTO部落格,原文連結:http://blog.51cto.com/nxlhero/887129,如需轉載請自行聯系原作者