在linux下,如何在C语言中使用正则表达式
生活随笔
收集整理的這篇文章主要介紹了
在linux下,如何在C语言中使用正则表达式
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
http://hi.baidu.com/d_south/blog/item/9d22a34b1fc2bcf483025c53.html
在linux下,如何在C語言中使用正則表達(dá)式(整理)
2008-03-18 19:17
? ? 一個(gè)正則表達(dá)式的教程可以參看(里面有個(gè)測試正則表達(dá)式的工具)
http://xyboy.co.cc/linux/ch32s02.html
? ?
? ? ?正則表達(dá)是用來匹配字符串的好東東。
? ?
? ? ?如果用戶熟悉Linux下的sed、awk、grep或vi,那么對正則表達(dá)式這一概念肯定不會(huì)陌生。由于它可以極大地簡化處理字符串時(shí)的復(fù)雜度,因此現(xiàn) 在已經(jīng)在許多Linux實(shí)用工具中得到了應(yīng)用。千萬不要以為正則表達(dá)式只是Perl、Python、Bash等腳本語言的專利,作為C語言程序員,用戶同 樣可以在自己的程序中運(yùn)用正則表達(dá)式。
? ??
? ? 標(biāo)準(zhǔn)的C和C++都不支持正則表達(dá)式,但有一些函數(shù)庫可以輔助C/C++程序員完成這一功能,其中最著名的當(dāng)數(shù)Philip Hazel的Perl-Compatible Regular Expression庫,許多Linux發(fā)行版本都帶有這個(gè)函數(shù)庫。
? ??
? ? 本人使用的是fedora 8系統(tǒng),該版本中就帶有這個(gè)函數(shù)庫,下面介紹一下如何使用。(實(shí)際上只要使用man命令查詢就可了解很多有關(guān)的細(xì)節(jié)了)
? ??
? ? 很多在網(wǎng)上都有介紹,但多有些小的錯(cuò)誤,于是我更改了并整理了一下。
? ? 要使用正則表達(dá)式的函數(shù)庫在你的程序前面包含
? ? #include <sys/types.h>?
? ? #include <regex.h>
? ? ?
? ? 下面介紹下如何使用:
? ? 首先,編譯正則表達(dá)式。
? ? 為了提高效率,在將一個(gè)字符串與正則表達(dá)式進(jìn)行比較之前,首先要用regcomp()函數(shù)對它進(jìn)行編譯,將其轉(zhuǎn)化為regex_t結(jié)構(gòu):
? ??
? ? int regcomp(regex_t *preg, const char *regex,int cflags);?
? ??
? ? 參數(shù)regex是一個(gè)字符串,它代表將要被編譯的正則表達(dá)式;參數(shù)preg指向一個(gè)聲明為regex_t的數(shù)據(jù)結(jié)構(gòu),用來保存編譯結(jié)果;參數(shù)cflags決定了正則表達(dá)式該如何被處理的細(xì)節(jié)。 (此處可以用man regcomp 命令查看詳細(xì)的解釋)
? ? 如果函數(shù)regcomp()執(zhí)行成功,并且編譯結(jié)果被正確填充到preg中后,函數(shù)將返回0,任何其它的返回結(jié)果都代表有某種錯(cuò)誤產(chǎn)生。?
? ??
? ? 接下來匹配正則表達(dá)式。
? ? 一旦用regcomp()成功地編譯了正則表達(dá)式,接下來就可以調(diào)用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; ? ?
? ? 參數(shù)preg指向編譯后的正則表達(dá)式,參數(shù)string是將要進(jìn)行匹配的字符串,而參數(shù)nmatch和pmatch則用于把匹配結(jié)果返回給調(diào)用程序,最后一個(gè)參數(shù)eflags決定了匹配的細(xì)節(jié)。?
? ? 在調(diào)用regexec()進(jìn)行模式匹配的過程中,可能在字符串string中會(huì)有多處與給定的正則表達(dá)式相匹配,參數(shù)pmatch就是用來保存這些匹配位置的,而參數(shù)nmatch則告訴regexec()最多可以把多少個(gè)匹配結(jié)果填充到pmatch數(shù)組中。當(dāng)regexec()成 功返回時(shí),從string+pmatch[0].rm_so到string+pmatch[0].rm_eo是第一個(gè)匹配的字符串,而從string+ pmatch[1].rm_so到string+pmatch[1].rm_eo,則是第二個(gè)匹配的字符串,依此類推。?
? ? 最后釋放正則表達(dá)式。
? ? 無論什么時(shí)候,當(dāng)不再需要已經(jīng)編譯過的正則表達(dá)式時(shí),都應(yīng)該調(diào)用regfree()將其釋放,以免產(chǎn)生內(nèi)存泄漏。?
? ? void regfree(regex_t *preg);?
? ? 報(bào)告錯(cuò)誤信息
? ?如果調(diào)用regcomp()或regexec()得到的是一個(gè)非0的返回值,則表明在對正則表達(dá)式的處理過程中出現(xiàn)了某種錯(cuò)誤,此時(shí)可以通過調(diào)用regerror()得到詳細(xì)的錯(cuò)誤信息。?
? size_t regerror(int errcode, const regex_t *preg, char *errbuf,size_t errbuf_size);?
? ? 參數(shù)errcode是來自regcomp()或regexec()的錯(cuò)誤代碼,而參數(shù)preg則是由regcomp()得到的編譯結(jié)果,其目的是把格式化消息所必須的上下文提供給regerror()。在執(zhí)行regerror()時(shí),將按照參數(shù)errbuf_size指明的最大字節(jié)數(shù),在errbuf緩沖區(qū)中填入格式化后的錯(cuò)誤信息,同時(shí)返回錯(cuò)誤信息的長度。?
? ? 給出一個(gè)應(yīng)用正則表達(dá)式的例子
? ? (這個(gè)例子網(wǎng)上容易找到,但多半有些小錯(cuò)誤,不能編譯成功,我將其修改寫在了下面)
例子如下:
#include <stdio.h>
#include <sys/types.h>
#include <regex.h>
/* 取子串的函數(shù) */?
static char* substr(const char*str,unsigned start, unsigned end)?
{?
? ? 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;?
? ? /* 編譯正則表達(dá)式*/?
? ? 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;?
? ? }?
? ? /* 逐行處理輸入的數(shù)據(jù) */?
? ? while(fgets(lbuf, sizeof(lbuf), stdin))
? ? {?
? ? ? ? ++lno;?
? ? ? ? if ((z = strlen(lbuf)) > 0 && lbuf[z-1]== '\n') lbuf[z - 1] = 0; ? ??
? ? ? ? /* 對每一行應(yīng)用正則表達(dá)式進(jìn)行匹配 */?
? ? ? ? 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;?
? ? ? ? }?
? ? ? ? /* 輸出處理結(jié)果 */?
? ? ? ? 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));?
? ? ? ? }?
? ? }?
?/* 釋放正則表達(dá)式 */?
? ? regfree(®); ? ??
? ? return 0;
}
上述程序負(fù)責(zé)從命令行獲取正則表達(dá)式,然后將其運(yùn)用于從標(biāo)準(zhǔn)輸入得到的每行數(shù)據(jù),并打印出匹配結(jié)果。執(zhí)行下面的命令可以編譯并執(zhí)行該程序:
? ? # gcc regexp.c -o regexp (編譯是會(huì)有兩個(gè)警告,沒有事)?
? ? # ./regexp 'regex[a-z]*' < regexp.c
? ??
? ? 0003: #include <regex.h>?
? ? $0='regex'?
? ? 0027: regex_t reg;?
? ? $0='regex'?
? ? 0054: z = regexec(?, lbuf, nmatch, pm, 0);?
? ? $0='regexec'
小結(jié)?
? ? 在C語言中使用正則表達(dá)式并不復(fù)雜。
? ? 正則表達(dá)式用來匹配復(fù)雜的字符串非常好用。
在linux下,如何在C語言中使用正則表達(dá)式(整理)
2008-03-18 19:17
? ? 一個(gè)正則表達(dá)式的教程可以參看(里面有個(gè)測試正則表達(dá)式的工具)
http://xyboy.co.cc/linux/ch32s02.html
? ?
? ? ?正則表達(dá)是用來匹配字符串的好東東。
? ?
? ? ?如果用戶熟悉Linux下的sed、awk、grep或vi,那么對正則表達(dá)式這一概念肯定不會(huì)陌生。由于它可以極大地簡化處理字符串時(shí)的復(fù)雜度,因此現(xiàn) 在已經(jīng)在許多Linux實(shí)用工具中得到了應(yīng)用。千萬不要以為正則表達(dá)式只是Perl、Python、Bash等腳本語言的專利,作為C語言程序員,用戶同 樣可以在自己的程序中運(yùn)用正則表達(dá)式。
? ??
? ? 標(biāo)準(zhǔn)的C和C++都不支持正則表達(dá)式,但有一些函數(shù)庫可以輔助C/C++程序員完成這一功能,其中最著名的當(dāng)數(shù)Philip Hazel的Perl-Compatible Regular Expression庫,許多Linux發(fā)行版本都帶有這個(gè)函數(shù)庫。
? ??
? ? 本人使用的是fedora 8系統(tǒng),該版本中就帶有這個(gè)函數(shù)庫,下面介紹一下如何使用。(實(shí)際上只要使用man命令查詢就可了解很多有關(guān)的細(xì)節(jié)了)
? ??
? ? 很多在網(wǎng)上都有介紹,但多有些小的錯(cuò)誤,于是我更改了并整理了一下。
? ? 要使用正則表達(dá)式的函數(shù)庫在你的程序前面包含
? ? #include <sys/types.h>?
? ? #include <regex.h>
? ? ?
? ? 下面介紹下如何使用:
? ? 首先,編譯正則表達(dá)式。
? ? 為了提高效率,在將一個(gè)字符串與正則表達(dá)式進(jìn)行比較之前,首先要用regcomp()函數(shù)對它進(jìn)行編譯,將其轉(zhuǎn)化為regex_t結(jié)構(gòu):
? ??
? ? int regcomp(regex_t *preg, const char *regex,int cflags);?
? ??
? ? 參數(shù)regex是一個(gè)字符串,它代表將要被編譯的正則表達(dá)式;參數(shù)preg指向一個(gè)聲明為regex_t的數(shù)據(jù)結(jié)構(gòu),用來保存編譯結(jié)果;參數(shù)cflags決定了正則表達(dá)式該如何被處理的細(xì)節(jié)。 (此處可以用man regcomp 命令查看詳細(xì)的解釋)
? ? 如果函數(shù)regcomp()執(zhí)行成功,并且編譯結(jié)果被正確填充到preg中后,函數(shù)將返回0,任何其它的返回結(jié)果都代表有某種錯(cuò)誤產(chǎn)生。?
? ??
? ? 接下來匹配正則表達(dá)式。
? ? 一旦用regcomp()成功地編譯了正則表達(dá)式,接下來就可以調(diào)用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; ? ?
? ? 參數(shù)preg指向編譯后的正則表達(dá)式,參數(shù)string是將要進(jìn)行匹配的字符串,而參數(shù)nmatch和pmatch則用于把匹配結(jié)果返回給調(diào)用程序,最后一個(gè)參數(shù)eflags決定了匹配的細(xì)節(jié)。?
? ? 在調(diào)用regexec()進(jìn)行模式匹配的過程中,可能在字符串string中會(huì)有多處與給定的正則表達(dá)式相匹配,參數(shù)pmatch就是用來保存這些匹配位置的,而參數(shù)nmatch則告訴regexec()最多可以把多少個(gè)匹配結(jié)果填充到pmatch數(shù)組中。當(dāng)regexec()成 功返回時(shí),從string+pmatch[0].rm_so到string+pmatch[0].rm_eo是第一個(gè)匹配的字符串,而從string+ pmatch[1].rm_so到string+pmatch[1].rm_eo,則是第二個(gè)匹配的字符串,依此類推。?
? ? 最后釋放正則表達(dá)式。
? ? 無論什么時(shí)候,當(dāng)不再需要已經(jīng)編譯過的正則表達(dá)式時(shí),都應(yīng)該調(diào)用regfree()將其釋放,以免產(chǎn)生內(nèi)存泄漏。?
? ? void regfree(regex_t *preg);?
? ? 報(bào)告錯(cuò)誤信息
? ?如果調(diào)用regcomp()或regexec()得到的是一個(gè)非0的返回值,則表明在對正則表達(dá)式的處理過程中出現(xiàn)了某種錯(cuò)誤,此時(shí)可以通過調(diào)用regerror()得到詳細(xì)的錯(cuò)誤信息。?
? size_t regerror(int errcode, const regex_t *preg, char *errbuf,size_t errbuf_size);?
? ? 參數(shù)errcode是來自regcomp()或regexec()的錯(cuò)誤代碼,而參數(shù)preg則是由regcomp()得到的編譯結(jié)果,其目的是把格式化消息所必須的上下文提供給regerror()。在執(zhí)行regerror()時(shí),將按照參數(shù)errbuf_size指明的最大字節(jié)數(shù),在errbuf緩沖區(qū)中填入格式化后的錯(cuò)誤信息,同時(shí)返回錯(cuò)誤信息的長度。?
? ? 給出一個(gè)應(yīng)用正則表達(dá)式的例子
? ? (這個(gè)例子網(wǎng)上容易找到,但多半有些小錯(cuò)誤,不能編譯成功,我將其修改寫在了下面)
例子如下:
#include <stdio.h>
#include <sys/types.h>
#include <regex.h>
/* 取子串的函數(shù) */?
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;?
? ? /* 編譯正則表達(dá)式*/?
? ? 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;?
? ? }?
? ? /* 逐行處理輸入的數(shù)據(jù) */?
? ? while(fgets(lbuf, sizeof(lbuf), stdin))
? ? {?
? ? ? ? ++lno;?
? ? ? ? if ((z = strlen(lbuf)) > 0 && lbuf[z-1]== '\n') lbuf[z - 1] = 0; ? ??
? ? ? ? /* 對每一行應(yīng)用正則表達(dá)式進(jìn)行匹配 */?
? ? ? ? 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;?
? ? ? ? }?
? ? ? ? /* 輸出處理結(jié)果 */?
? ? ? ? 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));?
? ? ? ? }?
? ? }?
?/* 釋放正則表達(dá)式 */?
? ? regfree(®); ? ??
? ? return 0;
}
上述程序負(fù)責(zé)從命令行獲取正則表達(dá)式,然后將其運(yùn)用于從標(biāo)準(zhǔn)輸入得到的每行數(shù)據(jù),并打印出匹配結(jié)果。執(zhí)行下面的命令可以編譯并執(zhí)行該程序:
? ? # gcc regexp.c -o regexp (編譯是會(huì)有兩個(gè)警告,沒有事)?
? ? # ./regexp 'regex[a-z]*' < regexp.c
? ??
? ? 0003: #include <regex.h>?
? ? $0='regex'?
? ? 0027: regex_t reg;?
? ? $0='regex'?
? ? 0054: z = regexec(?, lbuf, nmatch, pm, 0);?
? ? $0='regexec'
小結(jié)?
? ? 在C語言中使用正則表達(dá)式并不復(fù)雜。
? ? 正則表達(dá)式用來匹配復(fù)雜的字符串非常好用。
總結(jié)
以上是生活随笔為你收集整理的在linux下,如何在C语言中使用正则表达式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vi 查看头文件
- 下一篇: 有关volatile unsigned