c語言中的正規表示式regex h

2021-07-05 16:12:29 字數 2796 閱讀 7408

如果使用者熟悉linux下的sed、awk、grep或vi,那麼對正規表示式這一概念肯定不會陌生。由於它可以極大地簡化處理字串時的複雜度,因此現在已經在許多linux實用工具中得到了應用。千萬不要以為正規表示式只是perl、python、bash等指令碼語言的專利,作為c語言程式設計師,使用者同樣可以在自己的程式中運用正規表示式。 

標準的c和c++都不支援正規表示式,但有一些函式庫可以輔助c/c++程式設計師完成這一功能,其中最著名的當數philip hazel的perl-compatible regular expression庫,許多linux發行版本都帶有這個函式庫。 

為了提高效率,在將乙個字串與正規表示式進行比較之前,首先要用regcomp()函式對它進行編譯,將其轉化為regex_t結構: 

int regcomp(regex_t *preg, const char *regex, int cflags);

引數regex是乙個字串,它代表將要被編譯的正規表示式;引數preg指向乙個宣告為regex_t的資料結構,用來儲存編譯結果;引數cflags決定了正規表示式該如何被處理的細節。 

如果函式regcomp()執行成功,並且編譯結果被正確填充到preg中後,函式將返回0,任何其它的返回結果都代表有某種錯誤產生。 

一旦用regcomp()函式成功地編譯了正規表示式,接下來就可以呼叫regexec()函式完成模式匹配: 

int regexec(const    regex_t    *preg,    const    char *string, size_t nmatch,regmatch_t pmatch, int eflags);

typedef struct regmatch_t;

引數preg指向編譯後的正規表示式,引數string是將要進行匹配的字串,而引數nmatch和pmatch則用於把匹配結果返回給呼叫程式,最後乙個引數eflags決定了匹配的細節。 

在呼叫函式regexec()進行模式匹配的過程中,可能在字串string中會有多處與給定的正規表示式相匹配,引數pmatch就是用來儲存這些匹配位置的,而引數nmatch則告訴函式regexec()最多可以把多少個匹配結果填充到pmatch陣列中。當regexec()函式成功返回時,從string+pmatch[0].rm_so到string+pmatch[0].rm_eo是第乙個匹配的字串,而從string+pmatch[1].rm_so到string+pmatch[1].rm_eo,則是第二個匹配的字串,依此類推。 

無論什麼時候,當不再需要已經編譯過的正規表示式時,都應該呼叫函式regfree()將其釋放,以免產生記憶體洩漏。 

void regfree(regex_t *preg);

函式regfree()不會返回任何結果,它僅接收乙個指向regex_t資料型別的指標,這是之前呼叫regcomp()函式所得到的編譯結果。 

如果在程式中針對同乙個regex_t結構呼叫了多次regcomp()函式,posix標準並沒有規定是否每次都必須呼叫regfree()函式進行釋放,但建議每次呼叫regcomp()函式對正規表示式進行編譯後都呼叫一次regfree()函式,以盡早釋放占用的儲存空間。 

如果呼叫函式regcomp()或regexec()得到的是乙個非0的返回值,則表明在對正規表示式的處理過程中出現了某種錯誤,此時可以通過呼叫函式regerror()得到詳細的錯誤資訊。 

size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size);

引數errcode是來自函式regcomp()或regexec()的錯誤**,而引數preg則是由函式regcomp()得到的編譯結果,其目的是把格式化訊息所必須的上下文提供給regerror()函式。在執行函式regerror()時,將按照引數errbuf_size指明的最大位元組數,在errbuf緩衝區中填入格式化後的錯誤資訊,同時返回錯誤資訊的長度。 

最後給出乙個具體的例項,介紹如何在c語言程式中處理正規表示式。 

#include ;

#include ;

#include ;

/* 取子串的函式 */

static char* substr(const char*str, unsigned start, unsigned end)

/* 主程式 */

int main(int argc, char** argv)

/*    逐行處理輸入的資料 */

while(fgets(lbuf, sizeof(lbuf), stdin))

/* 輸出處理結果 */

for (x = 0; x < nmatch && pm[x].rm_so != -1; ++ x)

}/* 釋放正規表示式    */

regfree(®);

return 0;

}上述程式負責從命令列獲取正規表示式,然後將其運用於從標準輸入得到的每行資料,並列印出匹配結果。執行下面的命令可以編譯並執行該程式: 

#    gcc regexp.c -o regexp

#    ./regexp    'regex[a-z]*' < regexp.c

0003: #include ;

$0='regex'

0027:     regex_t reg;

$0='regex'

0054:       z = regexec(®, lbuf, nmatch, pm, 0);

$0='regexec'

對那些需要進行複雜資料處理的程式來說,正規表示式無疑是乙個非常有用的工具。本文重點在於闡述如何在c語言中利用正規表示式來簡化字串處理,以便在資料處理方面能夠獲得與perl語言類似的靈活性。

正規表示式regex

正規表示式 regular expression 是乙個字串,表示一定的規則 api文件的pattern類中有其具體的規則定義 注意 regex嚴格區分大小寫 package cn.itcast.demo02 public class regexdemo02 檢驗郵箱位址是否合法 規則 123456...

RegEx正規表示式

eg select prod name from products where prod name regexp 000 描述了乙個規則,通過這個規則可以匹配一類字串平台雲 字母 數字 漢字 下劃線 以及沒有特殊定義的標點符號,都是 普通字元 能夠與多種字元匹配的表示式 注意區分大小寫,大寫是相反的...

初學C 正規表示式(regex)

由效果產生學習的興趣,即使失敗,但至少不會中途作廢。正規表示式,語法看起來很多啊!位址參考 include header 1,匹配 號碼 string tel pattern 13 5 8 d 解釋 表示乙個子表示式,a,13是開頭 b,5 8 表示這個字元介於 5 和 8 之間 c,轉義,因為此處...