linux C regex正則表達式函數庫

C中的正則表達式如何實現呢,以regex系列函數來簡要說明:
 
標準的linux c與c++不支持正則表達式;
以POSIX函數庫中的Regex系列函數來說明在Linux c下如何使用正則表達式:
 
1、編譯正則表達式:
 
    Regcomp函數,生成regex_t數據結構;
 
    int Regcomp(regex_t *preg, const char *regex, int cflags);
     參數說明:
 
        preg:用來保存編譯的結果; 
        regex:字符串,表示被編譯的正則表達式;
        cflags:編譯開關控制細節;
              REG_EXTEND代表使用擴展正則表達式模式;
              REG_ICASE表示對規則中字符串不區分大小寫;
              REG_NOSUB只檢查是否有符合規則的子串
 
2、匹配正則表達式:
 
       利用regcomp生成的數據結構regex_t *preg 調用regexec()函數完成模式匹配:
       int regexec(
                        const regex_t *preg, 
                        const char *string, 
                        size_t match,
                        regmatch_t pmatch[],
                        int eflags
                        );
  typedef struct {
  regoff_t rm_so;
  regoff_t rm_eo;
  } regmatch_t;
 
     參數說明:
 
        preg:用來編譯後的模式匹配數據結構regex_t 常量; 
        string:字符串,表示被匹配的字符串;
        nmatch:被匹配的個數;
        pmatch:匹配的結果數組;
                rm_so 表示滿足規則的子串在string中的起始偏移量
                rm_eo 表示滿足規則的子串在string中的後續偏移量
        eflags:匹配的特性
                REG_NOTBOL 是否是第一行
                REG_NOTEOL 是否是最後一行
 
 
3、報告錯誤信息

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

 參數說明:
 
        errcode:來自regcomp及regexec函數的錯誤代碼; 
        preg:regcomp編譯結果;
        errbuf:緩衝區的錯誤信息字符串;
        errbuf_size:緩存區的錯誤信息字符串長度; 
 

4、釋放正則表達式:

void regfree(regex_t *preg);

               無返回結果,釋放regcomp編譯的regex_t指針;

5、正則表達式框架:
int mymatch(char *buf)
{
    const char *regex = "href=\"[^ >]*\"";
    regex_t preg;
    const size_t nmatch = 10;
    regmatch_t pm[nmatch];
    if (regcomp(&preg, regex, 0) != 0) {    /*編譯正則表達式失敗 */
        perror("regcomp");
        exit(1);
    }
    int z, i;
    z = regexec(&preg, buf, nmatch, pm, 0);
    if (z == REG_NOMATCH)/*無匹配項 */
    {   
        return 0;
    }
    else/*有匹配的超鏈接 */
    {       
        for (i = 0; i < nmatch && pm[i].rm_so != -1; ++i)/*把超鏈接都提取出*/
        {
            /*對匹配鏈接的操作*/
        }   
   
    }
    regfree(&preg);/*釋放正則表達式*/
}
6、正則表達式實例:

 

#include <stdio.h>

#include <sys/types.h>

#include <regex.h>

#include <string.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(&reg, pattern, cflags);

  if (z != 0)

  {

    regerror(z, &reg, 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(&reg, lbuf, nmatch, pm, 0);

    if (z == REG_NOMATCH) continue;

    else if (z != 0)

    {

      regerror(z, &reg, 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("d: %s\n", lno, lbuf);

      printf("  $%d='%s'\n", x, substr(lbuf, pm[x].rm_so, pm[x].rm_eo));

    }

  }

 

  regfree(&reg);

  return 0;

}



編譯執行

 

bitwangbin@mac:~/code/c/regex > gcc regexp.c -o regexp

bitwangbin@mac:~/code/c/regex > ./regexp  'regex[a-z]*' < regexp.c

0003: #include <regex.h>;

  $0='regex'

0020:   regex_t reg;

  $0='regex'

0037:     z = regexec(&reg, lbuf, nmatch, pm, 0);

  $0='regexec'

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章