看到妳們討論這方面的東西,做點貢獻,以示對本版的無私奉獻:哎呀:
如果用戶熟悉Linux下的sed、awk、grep或vi,那麽正則表達式的概念對他們來說肯定會很熟悉。因為它可以大大簡化處理字符串的復雜性
度,所以現在已經在很多Linux實用程序中應用了。千萬不要認為正則表達式只是Perl、Python、Bash等腳本語言的專利。,作為C語言程序。
成員,用戶也可以在自己的程序中使用正則表達式。
標準C和C++不支持正則表達式,但是有壹些函數庫可以輔助C/C++程序員完成這個功能。最著名的是Philip Hazel的兼容Perl的正則表達式庫,它包含在許多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 e flags);
typedef結構{
regoff _ t rm _ so
regoff _ t rm _ eo
} regmatch _ t;
參數preg指向編譯後的正則表達式,參數string是要匹配的字符串,參數nmatch和pmatch用於向調用程序返回匹配結果,最後壹個參數eflags決定匹配細節。
在通過調用函數regexec()進行模式匹配的過程中,字符串中給定的正則表達式可能存在多次匹配,使用參數pmatch來保證。
存儲這些匹配位置,參數nmatch告訴函數regexec()最多可以將多少個匹配結果填充到pmatch數組中。當regexec()函數成功返回時
Back,from 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()得到非零返回值,說明在處理正則表達式的過程中出現了某種錯誤,這時可以通過調用函數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 & ltstdio.h & gt;
# include & ltsys/types . h & gt;;
# include & ltregex.h & gt;
/*接受子串的函數*/
靜態char* substr(const char*str,無符號開始,無符號結束)
{
無符號n =結束-開始;
靜態char ST buf[256];
strncpy(stbuf,str + start,n);
ST buf[n]= 0;
返回stbuf
}
/*主程序*/
int main(int argc,char** argv)
{
char *模式;
int x,z,lno = 0,cflags = 0;
char ebuf[128],lbuf[256];
regex _ t reg
reg match _ t pm[10];
const size _ t n match = 10;
/*編譯正則表達式*/
pattern = argv[1];
z = regcomp(& amp;reg,pattern,cflags);
如果(z!= 0){
regerror(z & amp;reg,ebuf,sizeof(ebuf));
fprintf(stderr," %s: pattern '%s' \n ",ebuf,pattern);
返回1;
}
/*逐行處理輸入數據*/
while(fgets(lbuf,sizeof(lbuf),stdin)) {
++ lno;
if((z = strlen(lbuf))& gt;;0 & amp& amplbuf[z-1] == '\n ' '
lbuf[z-1]= 0;
/*對每壹行應用正則表達式進行匹配*/
z = regexec(& amp;reg,lbuf,nmatch,pm,0);
if (z == REG_NOMATCH)繼續;
else if (z!= 0) {
regerror(z & amp;reg,ebuf,sizeof(ebuf));
fprintf(stderr," %s: regcom('%s')\n ",ebuf,lbuf);
return 2;
}
/*輸出處理結果*/
for(x = 0;x & lt不匹配。& amppm[x]。rm_so!= -1;++ x) {
如果(!x) printf("%04d: %s\n ",lno,lbuf);
printf(" $%d='%s'\n ",x,substr(lbuf,pm[x])。rm_so,pm[x]。RM _ EO));
}
}
/*釋放正則表達式*/
regfree(& amp;reg);
返回0;
}
上面的程序負責從命令行獲取正則表達式,然後將它們應用於從標準輸入中獲取的每壹行數據,並打印出匹配結果。執行以下命令來編譯和執行程序:
# gcc正則表達式. c -o正則表達式
# ./regexp ' regex[a-z]* ' & lt;正則表達式c
0003:# include & lt;regex.h & gt;
$0='regex '
0027:regex _ t reg;
$0='regex '
0054:z = regexec(& amp;reg,lbuf,nmatch,pm,0);
$0='regexec '
總結
對於那些需要復雜數據處理的程序來說,正則表達式無疑是壹個非常有用的工具。本文重點介紹如何在C語言中使用正則表達式來簡化字符串處理,從而在數據處理中獲得類似Perl語言的靈活性。