c/c++ regex正则使用
来源:互联网 发布:国际大酒店网站源码 编辑:程序博客网 时间:2024/05/22 16:02
工作需要用到C++中的正则表达式,所以就研究了以上三种正则。
一、三种正则的比较
1. C regex
/* write by xingming * time:2012年10月19日15:51:53 * for: test regex * */#include <regex.h>#include <iostream>#include <sys/types.h>#include <stdio.h>#include <cstring>#include <sys/time.h>using namespace std;const int times = 1000000;int main(int argc,char** argv){ char pattern[512]="finance\.sina\.cn|stock1\.sina\.cn|3g\.sina\.com\.cn.*(channel=finance|_finance$|ch=stock|/stock/)|dp.sina.cn/.*ch=9&"; const size_t nmatch = 10; regmatch_t pm[10]; int z ; regex_t reg; char lbuf[256]="set",rbuf[256]; char buf[3][256] = {"finance.sina.cn/google.com/baidu.com.google.sina.cndddddddddddddddddddddda.sdfasdfeoasdfnahsfonadsdf", "3g.com.sina.cn.google.com.dddddddddddddddddddddddddddddddddddddddddddddddddddddbaidu.com.sina.egooooooooo", "http://3g.sina.com.cn/google.baiduchannel=financegogo.sjdfaposif;lasdjf.asdofjas;dfjaiel.sdfaosidfj"}; printf("input strings:\n"); timeval end,start; gettimeofday(&start,NULL); regcomp(®,pattern,REG_EXTENDED|REG_NOSUB); for(int i = 0 ; i < times; ++i) { for(int j = 0 ; j < 3; ++j) { z = regexec(®,buf[j],nmatch,pm,REG_NOTBOL);/* if(z==REG_NOMATCH) printf("no match\n"); else printf("ok\n"); */ } } gettimeofday(&end,NULL); uint time = (end.tv_sec-start.tv_sec)*1000000 + end.tv_usec - start.tv_usec; cout<<time/1000000<<" s and "<<time%1000000<<" us."<<endl; return 0 ;}
使用正则表达式可简单的分成几步:
1. 编译正则表达式
2. 执行匹配
3. 释放内存
首先,编译正则表达式
int regcomp(regex_t *preg, const char *regex, int cflags);
reqcomp()函数用于把正则表达式编译成某种格式,可以使后面的匹配更有效。
@param preg: regex_t结构体用于存放编译后的正则表达式;
@param regex: 指向正则表达式指针;
@param cflags:编译模式
共有如下四种编译模式:
· REG_EXTENDED:使用功能更强大的扩展正则表达式
· REG_ICASE:忽略大小写
· REG_NOSUB:不用存储匹配后的结果
· REG_NEWLINE:识别换行符,这样‘$’就可以从行尾开始匹配,‘^’就可以从行的开头开始匹配。否则忽略换行符,把整个文本串当做一个字符串处理。
其次,执行匹配
int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags);
@param preg: 已编译的正则表达式指针;
@param string:目标字符串;
@param nmatch:pmatch数组的长度;
@param pmatch:结构体数组,存放匹配文本串的位置信息;
regmatch_t 是一个结构体数据类型,在regex.h中定义:
typedef struct{ regoff_t rm_so; regoff_t rm_eo;} regmatch_t;
成员rm_so 存放匹配文本串在目标串中的开始位置,rm_eo 存放结束位置。通常我们以数组的形式定义一组这样的结构。因为往往我们的正则表达式中还包含子正则表达式。数组0单元存放主正则表达式位置,后边的单元依次存放子正则表达式位置
@param eflags:匹配模式
共两种匹配模式:
REG_NOTBOL:The match-beginning-of-line operator always fails to match (but see the compilation flag REG_NEWLINE above). This flag may be used when different portions of a string are passed to regexec and the beginning of the string should not be interpreted as the beginning of the line.
REG_NOTEOL:The match-end-of-line operator always fails to match (but see the compilation flag REG_NEWLINE above)
最后,释放内存
void regfree(regex_t *preg);
当使用完编译好的正则表达式后,或者需要重新编译其他正则表达式时,一定要使用这个函数清空该变量。
其他,处理错误
size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size);
当执行regcomp 或者regexec 产生错误的时候,就可以调用这个函数而返回一个包含错误信息的字符串。
@parm errcode: 由regcomp 和 regexec 函数返回的错误代号。
@parm preg: 已经用regcomp函数编译好的正则表达式,这个值可以为NULL。
@parm errbuf: 指向用来存放错误信息的字符串的内存空间。
@parm errbuf_size: 指明buffer的长度,如果这个错误信息的长度大于这个值,则regerror 函数会自动截断超出的字符串,但他仍然会返回完整的字符串的长度。所以我们可以用如下的方法先得到错误字符串的长度。
2. C++ regex
/* write by xingming * time:2012年10月19日15:51:53 * for: test regex * */#include <regex>#include <iostream>#include <stdio.h>#include <string>using namespace std;int main(int argc,char** argv){ regex pattern("[[:digit:]]",regex_constants::extended); printf("input strings:\n"); string buf; while(cin>>buf) { printf("*******\n%s\n********\n",buf.c_str()); if(buf == "quit") { printf("quit just now!\n"); break; } match_results<string::const_iterator> result; printf("run compare now! '%s'\n", buf.c_str()); bool valid = regex_match(buf,result,pattern); printf("compare over now! '%s'\n", buf.c_str()); if(!valid) printf("no match!\n"); else printf("ok\n"); } return 0 ;}
C++这个真心不想多说它,测试过程中发现 字符匹配的时候 ‘a’ 是可以匹配的,a+也是可以的,[[:w:]]也可以匹配任意字符,但[[:w:]]+就只能匹配一个字符,+号貌似不起作用了。所以后来就干脆放弃了这伟大的C++正则,如果有大牛知道这里面我错在哪里了,真心感谢你告诉我一下,谢谢。
3. boost regex
/* write by xingming * for:test boost regex * time:2012年10月23日11:35:33 * */#include <iostream>#include <string>#include <sys/time.h>#include "boost/regex.hpp"using namespace std;using namespace boost;const int times = 10000000;int main(){ regex pattern("finance\\.sina\\.cn|stock1\\.sina\\.cn|3g\\.sina\\.com\\.cn.*(channel=finance|_finance$|ch=stock|/stock/)|dp\\.sina\\.cn/.*ch=9&"); cout<<"input strings:"<<endl; timeval start,end; gettimeofday(&start,NULL); string input[] = {"finance.sina.cn/google.com/baidu.com.google.sina.cn", "3g.com.sina.cn.google.com.baidu.com.sina.egooooooooo", "http://3g.sina.com.cn/google.baiduchannel=financegogo"}; for(int i = 0 ;i < times; ++ i) { for(int j = 0 ; j < 3;++j) { //if(input=="quit") // break; //cout<<"string:'"<<input<<'\''<<endl; cmatch what; if(regex_search(input[j].c_str(),what,pattern)) ; // cout<<"OK!"<<endl; else ; // cout<<"error!"<<endl; } } gettimeofday(&end,NULL); uint time = (end.tv_sec-start.tv_sec)*1000000 + end.tv_usec - start.tv_usec; cout<<time/1000000<<" s and "<<time%1000000<<" us."<<endl; return 0 ;}
boost正则不用多说了,要是出去问,C++正则怎么用啊?那90%的人会推荐你用boost正则,他实现起来方便,正则库也很强大,资料可以找到很多,所以我也不在阐述了。
4. 对比情况
…
二、总结
C regex的速度让我吃惊啊,相比boost的速度,C regex的速度几乎要快上3倍,看来正则引擎的选取上应该有着落了!
上面的表格中我用到的正则和字符串是一样的(在代码中C regex的被我加长了),速度相差几乎有3倍,C的速度大约在30+w/s , 而boost的速度基本在15-w/s ,所以对比就出来了!
结果很显然,当然会选择C regex了。
三、补
c regex使用时发现对于待匹配的字符串中如果出现’\x00’字符时会无法匹配!例如,pattern”[0-9]{6,10}”, 字符串”aaaa,,,,\x00,,,123456。。。”,这种情况下无法匹配到”123456”,发生错误,如何解决还需要看下源码或者测试下boost regex吧,头疼!:(
最后问题解决了, 使用了HyperScan intel的一个好用的库!23333
四、引用
[1] C语言正则表达式详解 regcomp() regexec() regfree()详解 http://blog.csdn.net/yangbingzhou/article/details/51352648
[2] C++中三种正则表达式比较(C regex,C ++regex,boost regex) https://www.cnblogs.com/pmars/archive/2012/10/24/2736831.html
[3] 在MinGW使用正则表达式regex库 http://blog.creke.net/766.html
- c/c++ regex正则使用
- c正则--regex
- C++:Regex正则表达式
- C++:Regex正则表达式
- C++:Regex正则表达式
- 【C/C++】boost regex正则表达式的安装及使用
- C语言正则表达式regex
- 使用开源库 Objective-C RegEx Categories 处理正则表达式
- 使用开源库 Objective-C RegEx Categories 处理正则表达式
- 使用开源库 Objective-C RegEx Categories 处理正则表达式
- c语言中的正则表达式regex.h
- c语言中的正则表达式regex.h
- Linux C 正则表达式运用(regex.h)
- 日志 c/c++ 正则表达式 regex
- C语言的正则表达式 regex
- C#Regex正则表达式学习笔记
- C语言正则表达式库RegEx库
- C++中三种正则表达式比较(C regex,C ++regex,boost regex)
- Html之Frame的onreadystatechange 事件-yellowcong
- python学习笔记之使用threading模块实现多线程(转)
- 安装linux-generator
- ChannelOption.SO_BACKLOG, 1024-> java socket参数详解:BackLog
- 通用审批流程
- c/c++ regex正则使用
- TensorRT Samples: MNIST(Plugin, add a custom layer)
- 【mac+Android Studio】【持续集成优化】搭建Jenkins+svn+Android Studio+发布到蒲公英+发邮件
- 学习:C#读取ini配置文件数据
- docker-registry-web
- 高仿《One》APP Design + MVP + RxJava2 + Retrofit + Dagger2 + Realm
- input 默认宽度测试
- Flume Sink
- Echarts图表开发之饼图