分类: 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);
int regexec(const
size_t regerror(int errcode, const regex_t *preg, char *errbuf,
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);
}
#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);
}
这是一个比较通用的程序。它会读入整个文本文件作为一个字符串来进行匹配。并非按行读取。注意这行: while(regexec(&preg,cur,nmatch,pmatch,0)==0)
实验证明,实际上它每次执行regexec它找个第一个匹配结果就返回了。不要妄想它一下子把所有的匹配结果都找到把地址放到pmatch数组里。书上的写发很容易让人造成这种误解。因为它每次只匹配一个结果就返回,所以要循环匹配。
好了,先回去睡觉了。有空再写。时间不早了。