在C++ Builder6上使用Boost正则表达式库
正则表达式是一种模式匹配形式,它通常用在处理的文本程序中。比如我们经常使用的grep工具,还是perl语言都使用了正则表达式。传统的C++处理正则表达式是非常麻烦的,这也成为很多其他语言爱好者的笑柄,现在情况不一样了,因为有了boost。
Boost是一个基于Template的开发源代码库,在这个库中有很多子库用来高效处理各方面的问题,比如字符串拆分,格式化,线程等等,Boost对于每一个C++爱好者都是应该了解的,对于C++ Builder用户如果能在熟练使用VCL的情况下再熟练使用Boost,我想一定如虎添翼。
一般来说,使用Boost是非常简单,和使用其他STL库没有太大区别,但使用Boost的正则表达式库则不那么容易,因为这个库还需要我们单独编译,下面我将详细介绍如何使用。
如果你还不知道或者还没有Boost的话,你可以去www.boost.org下载最新版本,作者使用的是1.30版本。将下载下来的zip包[1]解压到任何你喜欢的目录,比如D:boost。
编译正则表达式库
前面已经提到,这个库需要我们单独编译才能使用,为什么不编译好一起发布呢?主要是考虑到不同的编译器需要不同的链接库文件和链接库太大了。在命令行下,进入[%Boost]LibsRegExBuild目录,直接敲入make –fbcb6.mak命令开始编译,这里请大家注意了,如果你的计算机上同时安装了BCB5,请一定要把path设置成为BCB6的bcc32.exe程序所在的目录,否则可能使用BCB5的make程序,这样虽然能编译但最后不能使用。
编译过程相当耗时,你需要耐心等待,最终编译完成,会在[%Boost]LibsRegExBuild目录生成一个BCB6目录,在这个目录生成了很多lib文件和dll文件,把所有dll文件复制到windows系统目录,所以lib文件复制到bcb6lib目录。如果你不想这么麻烦的复制文件,可以在编译时加入install参数,就像这样make –fBcb6.mak install,不过作者还是比较喜欢前一种方式,这样我可以知道到底生成了什么文件。现在编译已经完成了,你可以体现boost的神奇魅力了。
一个测试程序
在BCB6中创建console程序,编写下列代码:
|
#include<deque> #include<iostream> #include<algorithm> #include<boost/regex.hpp> int main() { using namespace boost; using namespace std; regex expression("s+hrefs*=s*"([^"]*)"",regbase::normal|regbase::icase); string s="<a href="index.html"><img src="logo.gif"></a>"; deque<string> result; regex_split(std::back_inserter(result),s,expression); copy(result.begin(),result.end(),ostream_iterator<string>(cout,"n")); int c; cin>>c; return 0; } |
设置BCB6 Project属性的Lib Path和Include Path为你安装boost的目录,运行你会看到结果:
index.html
可以看到index.html已经从字符串中提出出来了,那么为什么会是这样呢?
代码的核心部分是:
regex expression("s+hrefs*=s*"([^"]*)"",regbase::normal|regbase::icase);
它用来设置如何匹配字符串,上面乱七八糟的字符串很难看懂,如果不了解正则表达式的书写规则,上面代码可以和天书媲美。
regbase::normal|regbase::icase 是解析参数设置,具体可以参考boost帮助文档。
正则表达式的书写规则
具体的书写规则,大家可以参看boost的文档,我这里做一下简要说明:
|
. (dot) |
用来匹配任何一个字符,但不包括新行上的字符 |
|
* |
闭包,任意有限次的自重复连接 |
|
+ |
有限次自重复连接,但至少出现一次 |
|
{} |
指定可能的重复次数 |
|
例如: ba* 匹配 b ba baa baaa等 ba+ 匹配 ba baa baaaaaaaaa等 ba 匹配 ba baa baaa baaaa baaaaa |
|
|
转义字符,有很多用途,根据参数设置而变化,最常见的就是类似于c语言的用法 |
|
|
s |
匹配空格 |
|
w |
匹配一个单词 |
|
d |
匹配数字 |
|
() |
有两种用法: 1是合并的作用,例如(ab)*匹配ab abab ababab等 2是确定匹配,也就是说在()中的字符将被最终拆解出来 |
根据上面这张表,我们可以很容易知道前面的那段天书如何解释。
一个实际的例子
前一段时间在CSDN上有一篇帖子,问题是有一种文件结构如(类似):
@People{
Age=19
Speek=”Hay,,how are you”
}
问如何拆分字符串得到@后面的名字,=两边的属性名和属性值,引号里{}种的名字。
解决这个问题用正则表达式再合适不过了。
根据分析,我们可以这样构造匹配规则:
"@(.*?)s*{" 匹配@开始的字符创,后面两种类型如何构造匹配规则留给大家思考吧。
这样我们可以轻易拆解这个例子。
性能分析
通过上面的讨论,大家已经了解到boost的强大威力,那个性能又如何呢?为此我们再实际来拆分一个复杂的html代码,看看到底需要花费多少时间。
为了节省篇幅,这里就不列出html代码了,不过可以告诉大家,这是一个又Word生成的大小为186K的html文件,这个文件中用到了很多<table>标签,所以我这里测试就来拆分所有<table>标签的width属性。测试代码如下:
|
#include<deque> #include<iostream> #include<algorithm> #include<boost/regex.hpp> #include<vcl.h> int main() { using namespace boost; using namespace std; TStringList* html=new TStringList(); html->LoadFromFile("D:1.htm"); regex expression("s+width=([^"]*)s+",regbase::normal|regbase::icase); DWORD start=GetTickCount(); for(int n=0;n<html->Count;n++) { string s=html->Strings[n].c_str(); deque<string> result; regex_split(std::back_inserter(result),s,expression); copy(result.begin(),result.end(),ostream_iterator<string>(cout,"n")); result.clear(); } start=GetTickCount()-start; delete html; cout<<start; int c; cin>>c; return 0; } |
输出结果为671毫秒,拆分得到1072个width属性值,我们可以看到boost的效率是非常高的,虽然与一些角本语言比起来解析速度还是慢,但已经可以满足大多数编程要求了。另外作者的计算机配置并不是非常高,相信拿到现在任何一台主流配置的计算机上都会优于作者的结果。
结束语
其实上面的强大威力只是boost的冰山一角,如果你不自己去体会,你很难想象到boost的强大威力。在boost里还有很多使用的库,比如格式化输出,字符串拆解,类型转换等,这些库使用起来也比较方便,大家可以自行参考boost文档。在这些库中还有两个库需要自行编译,他们是python和thread库,而且这些库的编译需要专门的工具Jam,所以我们在编译这些库的时候还要编译jam工具,而编译jam工具也不是一件快乐的事情,麻烦同样出现在如果你安装了多个编译器,如果读者有兴趣可以自己试一下。
不过BCB6并不支持全部boost库,从boost提供的编译器支持表可以看到[2],BCB6还是有相当多的库不支持的,支持最好的是gcc/g++的编译器,但也不是全部支持。希望borland下一个将要发布的C++编译器可以支持更多C++标准。
在C++ Builder6上使用Boost正则表达式库的更多相关文章
- Boost正则表达式库regex常用search和match示例 - 编程语言 - 开发者第2241727个问答
Boost正则表达式库regex常用search和match示例 - 编程语言 - 开发者第2241727个问答 Boost正则表达式库regex常用search和match示例 发表回复 Boo ...
- VS2010中使用boost正则表达式库
1.下载boost库.http://www.boost.org/ 我下载的是boost_1_51_0版本.放在D:\opensource\boost_1_51_0. 2.编译boost库. 执 ...
- 站在巨人的肩膀上,C++开源库大全
程序员要站在巨人的肩膀上,C++拥有丰富的开源库,这里包括:标准库.Web应用框架.人工智能.数据库.图片处理.机器学习.日志.代码分析等. 标准库 C++ Standard Library:是一系列 ...
- 编译 pcre - 开源的正则表达式(库)
PCRE百科介绍: PCRE(Perl Compatible Regular Expressions)是一个Perl库,包括 perl 兼容的正则表达式库.这些在执行正规表达式模式匹配时用与Perl ...
- 如何在WINDOWS下编译BOOST C++库 .
如何在WINDOWS下编译BOOST C++库 cheungmine 2008-6-25 写出来,怕自己以后忘记了,也为初学者参考.使用VC8.0和boost1.35.0. 1)下载boost ...
- Boost线程库学习笔记
一.创建一个线程 创建线程 boost::thread myThread(threadFun); 需要注意的是:参数可以是函数对象或者函数指针.并且这个函数无参数,并返回void类型. 当一个thre ...
- Boost::thread库的使用
阅读对象 本文假设读者有几下Skills [1]在C++中至少使用过一种多线程开发库,有Mutex和Lock的概念. [2]熟悉C++开发,在开发工具中,能够编译.设置boost::thread库. ...
- boost 正则表达式 regex
boost 正则表达式 regex 环境安装 如果在引用boost regex出现连接错误,但是引用其他的库却没有这个错误,这是因为对于boost来说,是免编译的,但是,正则这个库 是需要单独编译 ...
- 一起学习Boost标准库--Boost.StringAlgorithms库
概述 在未使用Boost库时,使用STL的std::string处理一些字符串时,总是不顺手,特别是当用了C#/Python等语言后trim/split总要封装一个方法来处理.如果没有形成自己的com ...
随机推荐
- Altium Designer如何对齐原件
右边那个图标是排列菜单
- POJ 1274 The Perfect Stall || POJ 1469 COURSES(zoj 1140)二分图匹配
两题二分图匹配的题: 1.一个农民有n头牛和m个畜栏,对于每个畜栏,每头牛有不同喜好,有的想去,有的不想,对于给定的喜好表,你需要求出最大可以满足多少头牛的需求. 2.给你学生数和课程数,以及学生上的 ...
- python基础-合并列表
1.append() 向列表尾部追加一个新元素,列表只占一个索引位,在原有列表上增加 2.extend() 向列表尾部追加一个列表,将列表中的每个元素都追加进来,在原有列表上增加 3.+ 直接用+ ...
- [D3] Modify DOM Elements with D3 v4
Once you can get hold of DOM elements you’re ready to start changing them. Whether it’s changing col ...
- 【高德地图API】从零開始学高德JS API(五)路线规划——驾车|公交|步行
先来看两个问题:路线规划与导航有什么差别?步行导航与驾车导航有什么差别? 回答: 1.路线规划,指的是为用户提供3条路线推荐.[高德]在提供路线规划的时候,会提供用户自己定义路线规划功能,这是别家没有 ...
- 重构——DataTable转泛型
泛型简单介绍 泛型能够最大限度的重用代码.保护类型的安全.提高性能. 泛型最常见的用途是创建集合类 泛型数据类型中使用的信息可在执行时通过反射 ...
- 【习题 5-9 UVA - 1596】Bug Hunt
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] map模拟 map<string,int>记录每个数组的大小 map <pair<string, int&g ...
- [Angular] @ContentChild with Directive ref
For example you have a component, which take a trasclude input element: <au-fa-input id="pas ...
- hadoop调优之一:概述 分类: A1_HADOOP B3_LINUX 2015-03-13 20:51 395人阅读 评论(0) 收藏
hadoop集群性能低下的常见原因 (一)硬件环境 1.CPU/内存不足,或未充分利用 2.网络原因 3.磁盘原因 (二)map任务原因 1.输入文件中小文件过多,导致多次启动和停止JVM进程.可以设 ...
- div宽度设置width:100%后再设置padding或margin超出父元素的解决办法
div宽度设置width:100%后再设置padding或margin超出父元素的解决办法 一.总结 一句话总结:直接加上box-sizing:border-box;即可解决上述问题. 1.box-s ...