Chinaunix首页 | 论坛 | 博客

tyz

  • 博客访问: 28787
  • 博文数量: 9
  • 博客积分: 1505
  • 博客等级: 上尉
  • 技术积分: 100
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-22 16:57
文章分类
文章存档

2008年(9)

我的朋友
最近访客

分类: C/C++

2008-04-30 20:12:47

继续上一个话题
我们都知道标准的C和C++都不支持正则表达式,但有一些函数库可以辅助C/C++程序员完成这
一功能,其中最著名的当数Philip Hazel的Perl-Compatible Regular
Expression库,许多Linux发行版本都带有这个函数库。
如果你想查看的话,你只需要输入 man regcomp,然后打开你的金山词霸作为配合即可
编译正则表达式
据说目的是为了提高执行效率才这么干的,把你的正则式先给编了,在把编完了的正则式和你想分析或查找的字符串去匹配
 
int   regcomp   (regex_t   *compiled,   const   char   *pattern,   int   cflags)
 
功能说明:把pattern编译后才存到compiled中,成功编译返回0,否则,非0
参数说明:
regex_t   是一个结构体数据类型,用来存放编译后的规则表达式,它的成员re_nsub   用来存储规则表达式中的子规则表达式的个数,子规则表达式就是用圆括号包起来的部分表达式。   
pattern   是指向我们写好的规则表达式的指针。   
cflags   有如下4个值或者是它们或运算(|)后的值:   
REG_EXTENDED   以功能更加强大的扩展规则表达式的方式进行匹配。   
REG_ICASE   匹配字母时忽略大小写。   
REG_NOSUB   不用存储匹配后的结果。   
REG_NEWLINE   识别换行符,这样'$'就可以从行尾开始匹配,'^'就可以从行的开头开始匹配
 
匹配正则表达式
 
用regcomp()函数成功地编译了正则表达式,接下来就可以调用regexec()函
数完成模式匹配:
 
 int   regexec   (regex_t   *compiled,   char   *string,   size_t   nmatch,   regmatch_t   matchptr   [],   int   eflags)
 
功能说明:把你要分析或查找的字符串和存放编译好的正则式的preg进行匹配,成功编译返回0,否则,非0
当我们编译好规则表达式后,就可以用regexec   匹配我们的目标文本串了,如果在编译规则表达式的时候没有指定cflags的参数为REG_NEWLINE,则默认情况下是忽略换行符的,也就是把整个文本串当作一个字符串处理。执行成功返回0。   
参数说明:
regmatch_t   是一个结构体数据类型,成员rm_so   存放匹配文本串在目标串中的开始位置,rm_eo   存放结束位置。通常我们以数组的形式定义一组这样的结构。因为往往我们的规则表达式中还包含子规则表达式。数组0单元存放主规则表达式位置,后边的单元依次存放子规则表达式位置。  
   
  compiled   是已经用regcomp函数编译好的规则表达式。  
  string   是目标文本串。  
  nmatch   是regmatch_t结构体数组的长度。  
  matchptr   regmatch_t类型的结构体数组,存放匹配文本串的位置信息。  
  eflags   有两个值  
  REG_NOTBOL   我到现在还不是很明白这个参数的意义,可以参考Linux下的原文
 
释放正则表达式
 
无论什么时候,当不再需要已经编译过的正则表达式时,最好应该调用函数
regfree()将其释放,以免产生内存泄漏。在Linux原文中也没去强调的很清楚 
 
void regfree(regex_t *preg);
 
参数说明: 
preg:一个指向regex_t数据类型的指针
功能说明:
释放编译好了的正则表达式,防止产生内存泄露
 
报告错误信息
 
如果调用函数regcomp()或regexec()得到的是一个非0的返回值,则表明在对正则
表达式的处理过程中出现了某种错误,此时可以通过调用函数regerror()得到详
细的错误信息。
 
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);
 
下面是我的一个例子:
 
 #include
#include
#include
#include
#include
#include
char *zz="i$"; //regular expression for testing

int main(){
FILE* fp = NULL;
char msg[1000] = {0};
//for regular expression
char ebuf[128];//save regular expression's error
regex_t *reg; //a struct to save the result of bulid the regular expression
int z;
regmatch_t pm[10];
const size_t nmatch = 10;
int x;
int lno;
//end
int n;
fp = fopen("1", "r+");
if(fp == NULL){
        perror("fopen return error\n");
        exit(1);
    }
 

    //get the log
    while(fgets(msg, sizeof(msg), fp)){
        if(msg[0] == '#' || msg[0] == '\n')
            continue;
        if(strlen(msg) <1)
            continue;
        if(msg[strlen(msg)-1] == '\n'){
            msg[strlen(msg)-1] = '\0';
        }
        if(msg[strlen(msg)-2] == '\r'){
            msg[strlen(msg)-1] = '\0';
        }
        printf("The msg:%s\n",msg);
        //analysis msg
        //bulid
        if ((z=regcomp(reg, zz, REG_NEWLINE)) != 0)
        {  
        regerror(z, reg, ebuf, sizeof(ebuf));
        fprintf(stderr, "%s: zz '%s' \n",ebuf, zz);
        }
        //analysis
        z = regexec(reg, msg, nmatch, pm, 0);
        if (z != 0) {
         printf("**********\n");
         memset(msg, 0, sizeof(msg));
         regfree(reg);
         continue;
        }
      else{
                    printf("The msg who match the regular expression is: %s\n",msg);
                    regfree(reg);
                }//end else
                memset(msg, 0, sizeof(msg));
    }//end while

fclose(fp);
return 0;
}
 
我匹配的是所有以i结尾的字符串,待匹配的源字符串我是给放在一个文件中,存放字符串的文件为
当前目录下的1,你也可以自己在你的当前目录下建个1,并且在1里面写上你要分析的字符串信息,甚至你可以直接给出字符串让你的正则式来分析。总之,找到你喜欢的方式,享受编程的快感
 
Enjoy programming,enjoy Linux,enjoy CU,and enjoy your life! 
阅读(1341) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~