现在的位置: 首页 > 综合 > 正文

inux C 正则表达式

2012年12月10日 ⁄ 综合 ⁄ 共 3576字 ⁄ 字号 评论关闭

 下面介绍下如何使用:
    首先,编译正则表达式。
    为了提高效率,在将一个字符串与正则表达式进行比较之前,首先要用regcomp()函数对它进行编译,将其转化为regex_t结构:
   
    int regcomp(regex_t *preg, const char *regex,int cflags);
   
    参数regex是一个字符串,它代表将要被编译的正则表达式;参数preg指向一个声明为regex_t的数据结构,用来保存编译结果;参数cflags 决定了正则表达式该如何被处理的细节。(此处可以用man regcomp 命令查看详细的解释)
    如果函数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);

    报告错误信息
  
 如果调用regcomp()或regexec()得到的是一个非0的返回值,则表明在对正则表达式的处理过程中出现了某种错误,此时可以通过调用 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缓冲 区中填入格式化后的错误信息,同时返回错误信息的长度。

 

 

 

 

附:

1.int   regcomp   (regex_t   *compiled,   const   char   *pattern,   int   cflags)  
   
  这个函数把指定的规则表达式pattern编译成一种特定的数据格式compiled,这样可以使匹配更有效。函数regexec   会使用这个数据在目标文本串中进行模式匹配。执行成功返回0。  
   
  regex_t   是一个结构体数据类型,用来存放编译后的规则表达式,它的成员re_nsub   用来存储规则表达式中的子规则表达式的个数,子规则表达式就是用圆括号包起来的部分表达式。  
   
  pattern   是指向我们写好的规则表达式的指针。  
  cflags   有如下4个值或者是它们或运算(|)后的值:  
  REG_EXTENDED   以功能更加强大的扩展规则表达式的方式进行匹配。  
  REG_ICASE   匹配字母时忽略大小写。  
  REG_NOSUB   不用存储匹配后的结果。  
  REG_NEWLINE   识别换行符,这样'$'就可以从行尾开始匹配,'^'就可以从行的开头开始匹配。  
   
  2.   int   regexec   (regex_t   *compiled,   char   *string,   size_t   nmatch,   regmatch_t   matchptr   [],   int   eflags)  
   
  当我们编译好规则表达式后,就可以用regexec   匹配我们的目标文本串了,如果在编译规则表达式的时候没有指定cflags的参数为REG_NEWLINE,则默认情况下是忽略换行符的,也就是把整个文 本串当作一个字符串处理。执行成功返回0。  
   
  regmatch_t   是一个结构体数据类型,成员rm_so   存放匹配文本串在目标串中的开始位置,rm_eo   存放结束位置。通常我们以数组的形式定义一组这样的结构。因为往往我们的规则表达式中还包含子规则表达式。数组0单元存放主规则表达式位置,后边的单元依 次存放子规则表达式位置。  
   
  compiled   是已经用regcomp函数编译好的规则表达式。  
  string   是目标文本串。  
  nmatch   是regmatch_t结构体数组的长度。  
  matchptr   regmatch_t类型的结构体数组,存放匹配文本串的位置信息。  
  eflags   有两个值  
  REG_NOTBOL   按我的理解是如果指定了这个值,那么'^'就不会从我们的目标串开始匹配。总之我到现在还不是很明白这个参数的意义,   原文如下:  
  If   this   bit   is   set,   then   the   beginning-of-line   operator   doesn't   match   the   beginning   of   the   string   (presumably   because   it's   not   the   beginning   of   a   line).If   not   set,   then   the   beginning-of-line   operator   does   match   the   beginning   of   the   string.  
  REG_NOTEOL   和上边那个作用差不多,不过这个指定结束end   of   line。  
   
  3.   void   regfree   (regex_t   *compiled)  
   
  当我们使用完编译好的规则表达式后,或者要重新编译其他规则表达式的时候,我们可以用这个函数清空compiled指向的regex_t结构体的内容,请 记住,如果是重新编译的话,一定要先清空regex_t结构体。  
   
  4.   size_t   regerror   (int   errcode,   regex_t   *compiled,   char   *buffer,   size_t   length)  
   
  当执行regcomp   或者regexec   产生错误的时候,就可以调用这个函数而返回一个包含错误信息的字符串。  
   
  errcode   是由regcomp   和   regexec   函数返回的错误代号。  
  compiled   是已经用regcomp函数编译好的规则表达式,这个值可以为NULL。  
  buffer   指向用来存放错误信息的字符串的内存空间。  
  length   指明buffer的长度,如果这个错误信息的长度大于这个值,则regerror   函数会自动截断超出的字符串,但他仍然会返回完整的字符串的长度。所以我们可以用如下的方法先得到错误字符串的长度。  
  size_t   length   =   regerror   (errcode,   compiled,   NULL,   0);  

抱歉!评论已关闭.