加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

unix c正则表达式详解与实战

(2005-12-18 00:07:53)
分类: unix c编程
看到在chinaunix上问c正则的人很多,却没人能够解答,可能是正则不是c的强项,懂的人太少。甚至好多人不知道c还支持正则。
man regcomp 的时候解释的也很有限,至于我那本linux c函数库参考手册上写的那些规则根本就是不能用,他的例子甚至会让你产生误解。还有就是并非所有perl支持的功能c都支持,所以我想探讨一下经过我实验证明过的切实可行的方案。

      
 
int regcomp(regex_t *preg, const char *regex, int cflags);
int regexec(const  regex_t  *preg,  const  char *string, size_t nmatch,regmatch_t pmatch[], int eflags);
size_t regerror(int errcode, const regex_t *preg, char *errbuf,  size_t errbuf_size);
void regfree(regex_t *preg);                              
上面给出了函数原型,参数的用法看man就差不错了。我下面着重说编写表达式。
 
//code by yangjian:useage:  ./cmd regex < string.txt
#include<stdio.h>
#include<regex.h>
#define nmatch 1
//char* string="<div>;test</div>\n";
char string[4096];
char ret[1024];
main(int agrc,char *argv[])
{
// fgets(lbuf, sizeof(lbuf), stdin);

        regex_t preg;
        //char * regex="abc+";
        char * regex=argv[1];
        char * cur;
        regmatch_t pmatch [nmatch];
        int i;
        fread(string,sizeof(string),1,stdin);
        bzero(&preg,sizeof(regex_t));
        if(regcomp(&preg,regex,REG_EXTENDED)!=0)
        {
                printf("compile regex error!!");
        }
        cur=string;
        //printf("str: %s",cur);
        i=0;
        while(regexec(&preg,cur,nmatch,pmatch,0)==0)
        {
                //pmatch[0].rm_so==-1;
                //memset( pmatch, 0x00, sizeof(pmatch));
                        if(pmatch[0].rm_so==-1)
                        {
                                break;
                        }

                        memset( ret, 0x00, sizeof(ret));
                        memcpy( ret,cur+pmatch[0].rm_so,pmatch[0].rm_eo-pmatch[0].rm_so);
                        printf("%d: ",i++);
                        printf("%s\n\n",ret);
                        cur+=pmatch[0].rm_eo;
                        //printf("str: %s\n",cur);
        }
        regfree(&preg);
}

 
 
 
这是一个比较通用的程序。它会读入整个文本文件作为一个字符串来进行匹配。并非按行读取。注意这行: while(regexec(&preg,cur,nmatch,pmatch,0)==0)
实验证明,实际上它每次执行regexec它找个第一个匹配结果就返回了。不要妄想它一下子把所有的匹配结果都找到把地址放到pmatch数组里。书上的写发很容易让人造成这种误解。因为它每次只匹配一个结果就返回,所以要循环匹配。

 


好了,先回去睡觉了。有空再写。时间不早了。
 ./a.out "<td[a-z0-9=%<>/ ]+.{2,20}[ a-z/<>]+td>" < string.txt

 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有