LINUX C++ REGEXP 正则表达式

在POSIX中,便有着支持正则表达式的系统函数。GNU/Linux有两套库可用于正则表达式编程:POSIX库和PCRE库。前者不需要单独安装,一般需求还是能满足的,速度稍慢些。后者是久负盛名的Perl正则表达式库,功能强大,匹配速度快,不过可能需要单独安装。

 

int regcomp (regex_t *compiled, const char *pattern, int cflags)

    

参数compiled只有一个成员是我们需要关注的,那就是re_nsub,代表编译后的子表达式数目,由于我们还需要保存整个匹配到的模式,所以最终匹配的条目数是re_nsub加1。cflags用来修饰匹配模式,可取值如下:

REG_EXTENDED 启用POSIX正则库扩展,关于该扩展的详细信息可参考POSIX规范
REG_ICASE 忽略大小写
REG_NOSUB 不要存储子表达式
REG_NEWLINE 把换行符作为多行的分隔符,这样'$'可匹配每一行的行尾,'^'匹配每一行的行首,'.'不匹配换行符,[^...]不匹配新行。

 

参数regex是一个字符串,它代表将要被编译的正则表达式;参数preg指向一个声明为regex_t的数据结构,用来保存编译结果;参数cflags决定了正则表达式该如何被处理的细节。

  如果函数regcomp()执行成功,并且编译结果被正确填充到preg中后,函数将返回0,任何其它的返回结果都代表有某种错误产生。

  匹配正则表达式

  一旦用regcomp()函数成功地编译了正则表达式,接下来就可以调用regexec()函数完成模式匹配:

 

编译完模式后我们从内存中分配子表达式存储空间,然后调用regexec对串进行匹配,该函数原型如下:

  
  
  
  
int regexec (regex_t *compiled, char *string, size_t nmatch, regmatch_t matchptr [], int eflags)

nmatch指明matchptr数组的数目,该数目是compiled->re_nsub+1,也可以让nmatch为0,matchptr为NULL,表示不要保存子表达式。eflags通常为0。

参数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()函数所得到的编译结果。

 

报告错误信息

  如果调用函数regcomp()或regexec()得到的是一个非0的返回值,则表明在对正则表达式的处理过程中出现了某种错误,此时可以通过调用函数regerror()得到详细的错误信息。

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

 

代码如下:

#include <sys/types.h> #include <stdio.h> #include <regex.h> #include <iostream> #include <string.h> #include <stdlib.h> using namespace std; char *getsubstr(char*,char*,int,int); int main(int args,char *argc[]){ if(args<3){ exit(0); } cout << "regexp demo" << endl; regex_t ex; char *errormsg; int errorsize; int isreg_error=regcomp(&ex,argc[1],REG_NEWLINE); if(isreg_error!=0){ regerror(isreg_error,&ex,errormsg,errorsize); write(STDOUT_FILENO,errormsg,errorsize); }else{ int nmatch; regmatch_t *match=(regmatch_t*)malloc((ex.re_nsub+1)*sizeof(regmatch_t)); int matchs=regexec(&ex,argc[2],ex.re_nsub+1,match,0); cout << "argc[1]:" << argc[2] << endl; cout << "matchs:"<< matchs <<endl; cout << "nmatch:"<< ex.re_nsub+1 <<endl; cout << "REG_NOMATCH:" <<REG_NOMATCH << endl; if(matchs==REG_NOMATCH){ write(STDOUT_FILENO,"NO MATCH!",sizeof("NO MATCH!")); }else if(matchs!=0){ regerror(isreg_error,&ex,errormsg,errorsize); write(STDOUT_FILENO,errormsg,errorsize); }else{ cout << match->rm_so << endl; cout << match->rm_eo << endl; char *substr=NULL; getsubstr(argc[2],substr,match->rm_so,match->rm_eo); } } } char *getsubstr(char *wholestr,char *substr,int begin,int end){ write(STDOUT_FILENO,wholestr+begin,end-begin); substr=wholestr+begin; return substr; }

最后我们运行:

$ ./reg.exe ba* baaadddd
regexp demo
argc[1]:baaadddd
matchs:0
nmatch:1
REG_NOMATCH:1
0
4
baaa

可见代码运行正常。

你可能感兴趣的:(C++,linux,正则表达式,String,regex,newline)