#在vc6中使用PCRE-8.33
1. 引言
最近开发项目要遇到数据检验问题,打算使用正则表达式,因为它简单、高效,重要的是,不用把检验规则硬编码在程序里,放在配置文件中即可。由于使用的开发工具是vc6,不像vs2008那样已经自带boost的regex库。上网一查,最后在boost regex 和 PCRE 两个里选择。在编译速度上,boost regex 要慢一些;在运行速度上,PCRE在匹配简单字符串时更快,boost则在匹配较长字符串时略快。在综合考虑了大小和易用性之后,选择了PCRE。
2. PCRE简介
正则表达式(regular expression),通常简写为regex、regexp或RE,使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。
PCRE(Perl Compatible Regular Expressions),是一个函数库,由Philip Hazel开发,该函数库使用与Perl5一样的语法和语义实现了正则表达式的模式匹配功能。PCRE是免费开源的,它是由C语言实现。很多著名的开源软件如Apache、PHP、KDE、Nginx 等都使用了PCRE。官方主页--http://www.pcre.org,目前(2013.12)最新版本是8.33。
3. 如何在vc6中使用PCRE
####3.1 下载最新版PCRE
下载地址----ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/ windows用户下载扩展名为 zip 的文件就好。下载完成后,解压缩。
顺便提一下,也可以在这个网址(http://www.psyon.org/projects/pcre-win32/) 下载带vs工程文件的源码,但这个网站的版本要滞后于 PCRE 官网的。比如现在,官网的最新版本是8.33,而这个网站的最新版本是7.9。
####3.2 编译 PCRE
PCRE的作者Philip Hazel是在linux上工作的,所以编译PCRE最好的办法自然是configure, make, make install三步曲了。在windows下, cygwin或者MinGW都支持这么做,虽然它们二者其实是完全不同的。网上有许多文章也讲了手工编译PCRE的方法,虽然不是针对最新版本的,但略作修改,也是可行的(但要做到一键搞定,还要多下功夫才行)。
今天我要介绍的是用CMake。CMake是一种配置工具,可以用来代替“configure”。有越来越多的开源程序支持 CMake,因为其简单、实用、足够强大。
先从 http://www.cmake.org 上下载最新版的CMake,我是直接下载的安装包:cmake-2.8.12.1-win32-x86.exe。然后安装,最好安装到没有空格的目录下(事实上,这是个好习惯)。安装完成后别忘了把 cmake/bin 放到环境变量path中。
在解压缩后的PCRE目录下建个子目录build,比如我的D:\pcre-8.33\build。
进入控制台,然后先运行vc6的设置环境变量的批处理,我的机器上是D:\Program Files\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT,然后键入 cmake-gui ,回车。
-
设置要编译的源代码的路径以及编译好的二进制文件存放的路径
-
点"Configure"按钮,然后选择编译器,可以选择合适的编译器,因为我用的就是vc6,所以我选择了 "Visual Studio 6"。
-
CMake 会读取源代码目录下的文件 CMakeLists.txt ,然后将读到的配置以红颜色显示出来,此时可以根据我们的需要适当的选择或去掉一些配置,比如加上 PCRE_SUPPORT_UTF,去掉PCRE_SUPPORT_JIT(不需要嵌入式的代码)、PCRE_BUILD_PCRECPP(我只想要c形式的库);还可以修改一些配置的值,比如把PCRE_NEWLINE从LF改成CRLF。然后再点一下"Configure",最后点"Generate",你会发现在build目录里生成了一系列的vc6的工程文件以及一些.h文件和.c文件。我们最关心的是pcre.dsp。打开它,剩下的,对我们应该都不是问题了。:)
####3.3 在工程中使用PCRE
-
包含头文件 #include "pcre.h"
-
链接静态库 #pragma comment(lib,"pcre.lib")
-
在项目”预处理器定义“中加上PCRE_STATIC
-
示例代码:
pcre *myregexp; const char *error; int erroroffset; int offsetcount; int offsets[(0+1)*3]; // (max_capturing_groups+1)*3 myregexp = pcre_compile("\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}\\b", 0, &error, &erroroffset, NULL); if (myregexp != NULL) { offsetcount = pcre_exec(myregexp, NULL, subject, strlen(subject), 0, 0, offsets, (0+1)*3); while (offsetcount > 0) { // match offset = offsets[0]; // match length = offsets[1] - offsets[0]; if (pcre_get_substring(subject, &offsets, offsetcount, 0, &result) >= 0) { // Do something with match we just stored into result } offsetcount = pcre_exec(myregexp, NULL, subject, strlen(subject), 0, offsets[1], offsets, (0+1)*3); } } else { // Syntax error in the regular expression at erroroffset }
-
接口介绍: pcre *pcre_compile、pcre_exec
pcre *pcre_compile(const char *pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr); 功能:编译一个描述正则表达式的字符串 参数:pattern, 输入参数,将要被编译的字符串形式的正则表达式 options, 输入参数,用来指定编译时的一些选项 errptr, 输出参数,用来输出错误信息 erroffset, 输出参数,pattern中出错位置的偏移量 tableptr, 输入参数,用来指定字符表,一般情况用NULL, 使用缺省的字符表 返回值:被编译好的正则表达式的pcre内部表示结构 int pcre_exec(const pcre *code, const pcre_extra *extra, const char *subject, int length, int startoffset, int options, int *ovector, int ovecsize); 功能:用来检查某个字符串是否与指定的正则表达式匹配 参数: code, 输入参数,用pcre_compile编译好的正则表达结构的指针 extra, 输入参数,用来向pcre_exec传一些额外的数据信息的结构的指针 subject, 输入参数,要被用来匹配的字符串 length, 输入参数, 要被用来匹配的字符串的指针 startoffset, 输入参数,用来指定subject从什么位置开始被匹配的偏移量 options, 输入参数, 用来指定匹配过程中的一些选项 ovector, 输出参数,用来返回匹配位置偏移量的数组 ovecsize, 输入参数, 用来返回匹配位置偏移量的数组的最大大小 返回值:匹配成功返回非负数,匹配返回负数
简单的说,pcre_compile 把一个描述正则表达式的字符串编译成内部表示形式,之后就可以用pcre_exec来进行匹配、捕获等工作。
当然,PCRE的功能是非常强大的,远不止上面说的那么简单。剩下的就看我们自己的探索了。
顺便说一句:PCRE源代码目录下testdata目录中的那些输入和输出文件,本身就是很好的学习正则表达式极好的东西。