linux c 正則庫
linux c正則庫
標準的C和C++都不支持正則表達式,但是有一些函數庫提供這一功能,其中最著名的當數Philip Hazel的Perl-Compatible Regular Expression庫,許多Linux發行版本都帶有這個函數庫
3個重要的API
recomp()函數對其進行編譯,轉換爲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 {
regoff_t rm_so;
regoff_t rm_eo;
}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_terrbuf_size);
參數errcode是來自函數regcomp()或regexec()的錯誤代碼,而參數preg則是由函數regcomp()得到的編譯結果,其目的是把格式化消息所必須的上下文提供給regerror()函數。在執行函數regerror()時,將按照參數errbuf_size指明的最大字節數,在 errbuf緩衝區中填入格式化後的錯誤信息,同時返回錯誤信息的長度。
例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <regex.h>
static char* substr(const char* str,unsigned start,unsigned end)
{
unsigned n = end- start;
static char stbuf[256];
strncpy(stbuf,str+start,n);
stbuf[n] = '\0';
return stbuf;
}
int main(int argc,char **argv)
{
char *pattern;
int x,z,lno = 0,cflags = 0;
char ebuf[128],lbuf[256];
regex_t reg;
regmatch_t pm[10];
const size_t nmatch = 10;
pattern = argv[1];
z = regcomp(®,pattern,cflags);
if(z != 0)
{
regerror(z,®,ebuf,sizeof(ebuf));
fprintf(stderr,"%s:pattern '%s' \n",ebuf,pattern);
return 1;
}
while(fgets(lbuf,sizeof(lbuf),stdin))
{
++lno;
if((z = strlen(lbuf)) > 0 && lbuf[z-1] == '\n')
lbuf[z-1] = 0;
z = regexec(®,lbuf,nmatch,pm,0);
if(z == REG_NOMATCH)continue;
else if(z != 0)
{
regerror (z,®, ebuf, sizeof (ebuf));
fprintf (stderr, "%s: regcom('%s')\n", ebuf, lbuf);
return 2;
for(x = 0;x < nmatch && pm[x].rm_so != -1;++x)
{
if(!x)
printf("%04d:%s\n",lno,lbuf);
printf("$%d='%s'\n",x,substr(lbuf,pm[x].rm_so,pm[x].rm_eo));
}
}
regfree(®);
return 0;
}
標準的C和C++都不支持正則表達式,但是有一些函數庫提供這一功能,其中最著名的當數Philip Hazel的Perl-Compatible Regular Expression庫,許多Linux發行版本都帶有這個函數庫
3個重要的API
recomp()函數對其進行編譯,轉換爲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 {
regoff_t rm_so;
regoff_t rm_eo;
}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_terrbuf_size);
參數errcode是來自函數regcomp()或regexec()的錯誤代碼,而參數preg則是由函數regcomp()得到的編譯結果,其目的是把格式化消息所必須的上下文提供給regerror()函數。在執行函數regerror()時,將按照參數errbuf_size指明的最大字節數,在 errbuf緩衝區中填入格式化後的錯誤信息,同時返回錯誤信息的長度。
例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <regex.h>
static char* substr(const char* str,unsigned start,unsigned end)
{
unsigned n = end- start;
static char stbuf[256];
strncpy(stbuf,str+start,n);
stbuf[n] = '\0';
return stbuf;
}
int main(int argc,char **argv)
{
char *pattern;
int x,z,lno = 0,cflags = 0;
char ebuf[128],lbuf[256];
regex_t reg;
regmatch_t pm[10];
const size_t nmatch = 10;
pattern = argv[1];
z = regcomp(®,pattern,cflags);
if(z != 0)
{
regerror(z,®,ebuf,sizeof(ebuf));
fprintf(stderr,"%s:pattern '%s' \n",ebuf,pattern);
return 1;
}
while(fgets(lbuf,sizeof(lbuf),stdin))
{
++lno;
if((z = strlen(lbuf)) > 0 && lbuf[z-1] == '\n')
lbuf[z-1] = 0;
z = regexec(®,lbuf,nmatch,pm,0);
if(z == REG_NOMATCH)continue;
else if(z != 0)
{
regerror (z,®, ebuf, sizeof (ebuf));
fprintf (stderr, "%s: regcom('%s')\n", ebuf, lbuf);
return 2;
for(x = 0;x < nmatch && pm[x].rm_so != -1;++x)
{
if(!x)
printf("%04d:%s\n",lno,lbuf);
printf("$%d='%s'\n",x,substr(lbuf,pm[x].rm_so,pm[x].rm_eo));
}
}
regfree(®);
return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.