简介1
正则表达式(Regular expression)是一种在文本处理中经常用到的模式匹配的形式,可能许多用户熟悉Unix下的grep,sed,awk等工具或者perl语言,它们都广泛地用到了正则表达式。传统的C++用户还受限于用POSIX C API's(Portable operateing system interface standard)来操作正则表达式,而regex++已经提供了这些API's,虽然它不一定是使用POSIX C 正则表达式库的最好方法。比如regex++能处理宽字符字符串(wide character strings),或者搜索、替换操作(在某种意义上类似于sed或perl),这些在传统的C 库中是不能实现的。
类boost::reg_expression是regex++库中的关键类,它表示“机器可读”的正则表达式,reg_expression 是在string的基础之上构建的,可以认为它是一个具有string的功能,外加这个正则表达式算法所需要的状态机。
像std::basic_string一样,它提供了两个针对char和wchar_t的特化版本:
namespace boost{
template <class charT,
class traits = regex_traits<charT>,
class Allocator = std::allocator<charT> >
class basic_regex;
typedef basic_regex<char> regex;
typedef basic_regex<wchar_t> wregex;
}
要知道regex++库到底有什么用?可以试想我们要写一个信用卡处理程序。信用卡通常有16位数字组成的号码,其中每四位一组,用空格或连字号隔开。在将这些信用卡号码存入数据库之前,我们难道不要检验这些数字是否符合正确格式么?为了匹配任何一个数字我们可以用正则表达式[0-9],数字串的宽度可以用[[:digit:]],当然这些是POSIX标准。在regex++和perl中可简化为\d(注意许多老的库倾向于硬编码到C-locale,因此这不是什么问题)。下面的正则表达式可以检验信用卡号码的格式。
(\d{4}[- ]){3}\d{4}
()标记子表达式,{4}表示重复4次。这仅是一个perl,awk,egrep的正则表达式的例子。regex++也支持那些sed,grep用到的比较老的“基本”语法,虽然它们很少用到,除非你需要重用一些已有的基本正则表达式。
现在让我们把这个表达式置于C++代码中来检验信用卡号码的格式:
bool validate_card_format(const std::string s)
{
static const boost::regex e("(\d{4}[- ]){3}\\d{4}");
return regex_match(s, e);
}
注意我们以前是如何将某些额外的转义序列(或者翻译成:转义字符)添加到表达式的:要知道,正则表达式引擎处理转义字符前,该转义字符只能被 C++编译器识别一次,因此,在C++代码中嵌入正则表达式的转义字符必须双写(写两次)。
还要注意到你的编译器必须支持Koening lookup 2(比如VC6就不支持),否则你需要附加一些boost::prefixes到某些函数引用中。
那些熟悉信用卡操作的人,可能还会想到上面的那种格式适合于人的阅读,并不表示网上信用卡系统要求的格式(可能是16或15个没有间隔符的数字串)。我们需要一种简单的转换方法,我们需要2个字符串,1个是正则表达式,一个是格式字符串(提供一种被匹配的内容的描述)。在regex++中,search和replace都能完成regex_merge算法,对于信用卡的例子我们给出了下面2个算法用于格式转换:
// match any format with the regular expression:
const boost::regex e("\A(\d{3,4})[- ]?(\d{4})[- ]?(\d{4})[- ]?(\d{4})\z");
const std::string machine_format("\1\2\3\4");
const std::string human_format("\1-\2-\3-\4");
std::string machine_readable_card_number(const std::string s)
{
return regex_merge(s, e, machine_format, boost::match_default | boost::format_sed);
}
std::string human_readable_card_number(const std::string s)
{
return regex_merge(s, e, human_format, boost::match_default | boost::format_sed);
}
这儿,我们用正则表达式中的子式把号码分为4块,format string 用类似sed的语法把被匹配的内容替换为规定格式。
上面的例子中,我们还没有直接操作匹配结果,匹配结果包括全体匹配和一些子式的匹配。当需要正则表达式的匹配结果时,就需要用到class match_results的实例,下面是常用类型的特化版本:
namespace boost{
typedef match_results<const char*> cmatch;
typedef match_results<const wchar_t*> wcmatch;
typedef match_results<std::string::const_iterator> smatch;
typedef match_results<std::wstring::const_iterator> wsmatch;
}
regex_search和regex_grep算法都使用到match_result。
注意这些算法并不局限于一般的C-strings,任何双向迭代器(bidirectional iterator)类型都能被搜索,这为无缝搜索任何类型数据提供了可能性。
对于那些不喜欢模板(templates)的人还可以使用class RegEx,它是对模板代码的高层次包装,它为那些使用不到库的整个功能的人提供了简单的接口,当然它仅支持窄字符(narrow character)和“扩展”的正则表达式语法。
对于想兼容POSIX的人可以使用POSIXAPI函数:regcomp,regexec,regfree,regerror,这些对narrow character和Unicode都适用。
最后注意,这个库现在支持运行时本地化(run-time localization),它能完全识别POSIX正则表达式语法,包括一些多字符的元素比较和同等类型的高级特性,它还能兼容其它一些正则表达式库包括GNU、BSD4的regex包。
安装和配置
首先当你从zip文件解压本库时必须保留它的内部结构,如果你没这样做,那只好删除你解压的文件,重现来一次。
由于支持大多数常见的编译器/标准库/平台,这个库不需要作使用前的配置。如果你碰到配置问题,或想测试你的编译器的配置信息,可以参考 配置文档(这和boost的其它所有的库的处理过程都一样)。
由于本库混合了模板代码(头文件中)和静态代码数据(cpp文件中),所以在你使用之前,必须将库支持的代码 生成到库内和档案文件中。以下是几个具体平台的操作步骤:
Borland C++ Builder
略
Microsoft Visual C++ 6 and 7
如果你使用VC5,你可能要找一下本库的以前版本。
打开命令提示符(其MSVC环境变量必须已定义,如果没有可运行Vcvars32.bat,位于<VC6>\bin),进入<boost>\libs\regex\build 目录
选择正确的makefile,VC6++的是vc6.mak,支持STLPort的是vc6-stlport.mak
如下调用
nmake -fvc6.mak
如果想在VC6子目录包含所有的lib、dll文件,lib文件拷在<VC6>\lib,dll文件拷在<VC6>\bin,可使用
nmake -fvc6.mak install
删除生成过程中所有的临时文件,可使用
nmake -fvc6.mak clean
最后只需添加<boost>根目录到你的工程所包含的目录列表中。没有必要手动将*.lib文件加到工程中,因为在头文件会选择正确的.lib文件。
注意:如果想静态地链入regex库,可定义BOOST_REGEX_STATIC_LINK(在release版中生效)。
如果想直接使用源文件,可定义BOOST_REGEX_NO_LIB,这样自动选择库将失效。
1.简介出处:http://www.boost.org/libs/regex/doc/introduction.html
2.Koening lookup:When a function is called, in order to determine if that function is visible in the current scope, the namespaces in which the functions parameters reside must be taken into account.