• 熟悉linux的用户一定用过ls命令。而ls命令参数是支持正则表达式的。要不然我想看100个文件的信息,岂不是要输入100个文件名。同理统计程序注释行数设计到的程序文件也可能有很多,所有,支持正则表达式是必须的。

    其实,在C语言下也可以使用正则表达式,当然C标准里没有这些库函数,目前包含正则表达式的函数库有两个:POSIX以及PERL。通常LINUX的各个版本中都有POSIX库,而PERL库就需要另外安装。介于这个原因,本程序中使用POSIX库.

    具体POSIX库中关于正则表达式函数使用可以参考这篇帖子,很详细,还有例子。

    主要是以下4个函数的使用(linux下直接 man 3 regex就可以看到):

    SYNOPSIS
           #include <sys/types.h>
           #include <regex.h>

    1.        int regcomp(regex_t *preg, const char *regex, int cflags);
    2.        int regexec(const regex_t *preg, const char *string, size_t nmatch,regmatch_t pmatch[], int eflags);
    3.        size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size);
    4.        void regfree(regex_t *preg);

     

    主要程序如下:

    23 #define     BUFFSIZE        128u            /* buffer size */
     24
     25 /*-----------------------------------------------------------------------------
     26  *  Description:  According to the regex,judge whether the filename
     27  *                matches the regex or not.
     28  *-----------------------------------------------------------------------------*/
     29 Boolean_e
     30 is_string_matched_regex (
     31         const char *filename,                   /*  filename string needed to match  */
     32         const char *pattern                     /*  regex pattern  */
     33         )
     34 {
     35     Boolean_e   is_matched = FALSE;
     36     uint32  matched_no = 0;
     37     uint32  ret = 0;
     38     uint8   err_buf[BUFFSIZE] = {0};
     39
     40     regex_t reg;
     41     regmatch_t pm[10];                          /*  the array storing the matched result */
     42     const size_t nmatch = 10;
     43
     44     RETURN_VAL_IF_FAIL(filename == NULL, FALSE);
     45     RETURN_VAL_IF_FAIL(pattern != NULL, FALSE);
     46
     47 #ifdef  DEBUG
     48     printf("%s is processing...\n",__FUNCTION__);
     49 #endif     /* -----  DEBUG  ----- */
     50
     51     /*-----------------------------------------------------------------------------
     52      * compile the regex
     53      * using (Extend |Insensitive Case | Newline) POSIX regx
     54      *-----------------------------------------------------------------------------*/
     55     ret = regcomp(&reg, pattern, REG_EXTENDED|REG_ICASE|REG_NEWLINE);
     56     if (ret != 0)
     57     {
     58         regerror(ret, &reg, err_buf, sizeof(err_buf));
     59         fprintf(stderr, "%s: filename '%s' \n", err_buf,filename);
     60         is_matched = FALSE;
     61
     62         return(is_matched);
     63     }
     64
     65     /*  exec the regex match*/
     66     ret = regexec(&reg, filename, nmatch, pm, 0);
     67
     68     if (ret == REG_NOMATCH )
     69     {
     70         is_matched = FALSE;
     71
     72         return(is_matched);
     73     }
     74     else
     75         if (ret != 0)
     76         {
     77             regerror(ret, &reg, err_buf, sizeof(err_buf));
     78             fprintf(stderr, "%s: regcom('%s')\n", err_buf, filename);
     79             is_matched = FALSE;
     80
     81             return(is_matched);
     82         }
     83
     84     /*  judge if matched according to the regexec's result */
     85     for (matched_no = 0; matched_no < nmatch && pm[matched_no].rm_so != -1; ++ matched_no)
     86     {
     87         /*result = substr(filename, pm[matched_no].rm_so, pm[matched_no].rm_eo);*/
     88
     89         if( pm[matched_no].rm_so == 0
     90                 && pm[matched_no].rm_eo == strlen(filename))
     91         {
     92             is_matched = TRUE;
     93             break;
     94         }
     95     }
     96
     97     /*  release regex  */
     98     regfree(&reg);
     99
    100     return(is_matched);
    101 }       /* -----  end of function is_string_matched_regex  ----- */

    实现单个文件名与正则表达式的匹配之后,只需要遍历当前目录下的所有文件名,重复匹配。

    测试程序如下:

    int main(int argc, char *argv[])
    105 {
    106     Boolean_e is_matched = FALSE;
    107     uint16  file_no = 0;
    108
    109     DIR *dp = NULL;
    110     struct   dirent   *dirp = NULL;
    111
    112     /*-----------------------------------------------------------------------------
    113      *  open the current directoty.
    114      *-----------------------------------------------------------------------------*/
    115     if((dp = opendir("."))== NULL)
    116     {
    117         printf("can't open the current directoty!\n");
    118         exit(0);
    119     }
    120
    121     /* get filename in the current directoty,and match the regex.   */
    122     while((dirp = readdir(dp))!=NULL)
    123     {
    124         file_no++;
    125         is_matched = is_string_matched_regex(dirp->d_name, argv[1]);
    126
    127 #ifdef  DEBUG
    128         if( is_matched == TRUE )
    129         {
    130             printf("file_no:%d---filename:%s\n",file_no, dirp->d_name);
    131         }
    132 #endif     /* -----   DEBUG  ----- */
    133     }
    134
    135     closedir(dp);
    136
    137     return 0;
    138 }