C语言使用正则表达式(常规方法)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C语言使用正则表达式
据说一个好的程序员是会使用DB和Regular Expression的程序员,可见两者是多么重要。正则表达式是能极大地提高工作效率的工具,使用过Linux下各种具备RE特性的工具的人一定对此深有感触。很多语言都支持RE,用的最多的当然是脚本,其中以perl最盛。不过,用C语言来用RE不是很多见,但是有时候也很有用,我最近也是看到别人说道这个,所以搜了一些资料加上自己的体会来说一说RE在C语言里的应用。C语言本身不具备RE特性,但是有很多库,在Linux下你可以很方便的使用regex.h提供的库。我先贴一段代码展示一下RE在C语言里是怎么用的
1 #include
2 #include
3 #include
4 #include
5 #include
6
7 int main(){
8
9 char*bematch ="********************";
10 char*pattern ="h{3,10}(.*)@.{5}.(.*)";
11 char errbuf[1024];
12 char match[100];
13 regex_t reg;
14 int err,nm =10;
15 regmatch_t pmatch[nm];
16
17 if((err=regcomp(®,pattern,REG_EXTENDED))<0){
18 regerror(err,®,errbuf,sizeof(errbuf));
19 printf("err:%s\n",errbuf);
20 }
21
22 err =regexec(®,bematch,nm,pmatch,0);
23
24 if(err ==REG_NOMATCH){
25 printf("no match\n");
26 exit(-1);
27 }else if(err){
28 regerror(err,®,errbuf,sizeof(errbuf));
29 printf("err:%s\n",errbuf);
30 exit(-1);
31 }
32
33 for(int i=0;i<10 &&pmatch[i].rm_so!=-1;i++){
34 int len =pmatch[i].rm_eo-pmatch[i].rm_so;
35 if(len){
36 memset(match,'\0',sizeof(match));
37 memcpy(match,bematch+pmatch[i].rm_so,len);
38 printf("%s\n",match);
39 }
40 }
41 return0;
42 }
我打算看看一个邮件地址是否匹配我所提供的pattern。这个邮件地址是
******************** patern为
"h{3,10}(.*)@.{5}.(.*)"
我们希望匹配一个以3个h字符接着为任意字符串(可以为空)直到遇到一个@,然后接5个任意的字符和一个.号,最后再接一个字符串(可以为空),我们运行得到的结果是
********************
ericchd
com
我们发现,这个邮件地址被匹配了,第一行输出了,第二行和第三行分别输出的是我们希望得到的匹配的一部分,也就是在pattern中用括号括起来的部分。在这里我们还发现,在C语言里使用RE表达式的时候和通常的UNIX一般的RE表达式有区别:
第一、\{\}和\(\)需要改成{}和(),因为在C语言反斜杠是转移字符用的
第二、.不需要转义,不想UNIX的RE那样需要\.,但是?和*我没有找到该怎么用
下面贴上对以上所用函数的一些解释
regex的使用
需要用到以下几个函数。(定义在/usr/include/regex.h文件中)
int regcomp (regex_t *compiled, const char *pattern, i nt cflags) int regexec (regex_t *compiled, char *stri ng, size_t nmatch, regmatch_t matchptr [], int eflags )
void regfree (regex_t *compiled)
size_t regerror (int errcode, regex_t *compiled, char *buffer, size_t length)
1.int regcomp (regex_t *compiled, const char *pattern, int cflags)
这个函数把指定的规则表达式pattern编译成一种特定的数据格式compiled,这样可以使匹配更有效。函数regexec 会使用这个数据在目标文
本串中进行模式匹配。执行成功返回0。
regex_t 是一个结构体数据类型,用来存放编译后的规则表达式,它的成员re_nsub 用来存储规则表达式中的子规则表达式的个数,子规则表达式就是用圆括号包起来的部分表达式。
pattern 是指向我们写好的规则表达式的指针。
cflags 有如下4个值或者是它们或运算(|)后的值:
REG_EXTENDED 以功能更加强大的扩展规则表达式的方式进行匹
配。
REG_ICASE 匹配字母时忽略大小写。
REG_NOSUB 不用存储匹配后的结果。
REG_NEWLINE 识别换行符,这样'$'就可以从行尾开始匹配,'^'就可以从行的开头开始匹配。
2. int regexec (regex_t *compiled, char *string, size_ t nmatch, regmatch_t matchptr [], int eflags)
当我们编译好规则表达式后,就可以用regexec 匹配我们的目标文本