如何在C语言中使用正则表达式
看到你们讨论这方面的东西,做点贡献,以示对本版的无私奉献:哎呀:
如果用户熟悉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语言的灵活性。