boost::regex类为C++提供了完整的正则表达式支持,并且已被接收为C++0x标准库。它同时也在Boost库中扮演着极重要的角色,不少Boost子库都需要它的支持,有不少人甚至就是为了它才下载使用Boost的。
完整编译请参考本站编译Boost的文章
如果只要编译Regex库,有两种方法(参考链接):
Boost.Regex手里有七种武器和两大法宝
其中的七种武器是:
regex_match 函数 regex_search 函数 regex_replace 函数 regex_format 函数 regex_grep 函数 regex_split 函数 RegEx 类
每种武器都又有诸多变化(每个函数都分别以C字符串类型、std::string类型、迭代器类型作为参数重载),不过后面四种武器因年久失修已不建议使用.
两大法宝是:
regex_iterator 迭代器 regex_token_iterator 迭代器
这两大法宝是整个Boost.Regex的灵魂,用熟它们以后那是“摘花飞叶即可伤人”啊~~
#include <boost/regex.hpp>
先准备一个测试用的数据备用,如果各位有雅兴可以参考本站的另一篇文章《Google Testing》使用Google Testing框架来做这个实验,花一样时间学两样啊~~
#include <iostream> #include <boost/regex.hpp> using namespace std; int main(int argc, char* argv[]) { //( 1 ) (( 3 ) 2 )(( 5 )4)( 6 ) //(/w+)://((/w+/.)*/w+)((//w*)*)(//w+/./w+)? //^协议://网址(x.x...x)/路径(n个/字串)/网页文件(xxx.xxx) const char *szReg = "(//w+)://((//w+//.)*//w+)((///w*)*)(///w+//.//w+)?"; const char *szStr = "http://www.cppprog.com/2009/0112/48.html"; //练习代码... cin.get(); //暂停 }
要确定一行字符串是否与指定的正则表达式匹配,使用regex_match。
下面这个代码可以验证szStr字串(定义在上面)是否与szReg匹配。
{ //字符串匹配 boost::regex reg( szReg ); bool r=boost::regex_match( szStr , reg); assert(r); //是否匹配 }
boost::regex的构造函数中还可以加入标记参数用于指定它的行为,如:
//指定使用perl语法(默认),忽略大小写。 boost::regex reg1( szReg, boost::regex::perl|boost::regex::icase ); //指定使用POSIX扩展语法(其实也差不多) boost::regex reg2( szReg, boost::regex::extended );
下面这个代码不仅验证是否匹配,而且可以从中提取出正则表达式括号对应的子串。
{ //提取子串 boost::cmatch mat; boost::regex reg( szStr ); bool r=boost::regex_match( szStr, mat, reg); if(r) //如果匹配成功 { //显示所有子串 for(boost::cmatch::iterator itr=mat.begin(); itr!=mat.end(); ++itr) { // 指向子串对应首位置 指向子串对应尾位置 子串内容 cout << itr->first-szStr << ' ' << itr->second-szStr << ' ' << *itr << endl; } } //也可直接取指定位置信息 if(mat[4].matched) cout << "Path is" << mat[4] << endl; }
其中,boost::cmatch是一个针对C字符串的特化版本,它还有另三位兄弟,如下:
typedef match_results<const char*> cmatch; typedef match_results<std::string::const_iterator> smatch; typedef match_results<const wchar_t*> wcmatch; typedef match_results<std::wstring::const_iterator> wsmatch;
可以把match_results看成是一个sub_match的容器,同时它还提供了format方法来代替regex_format函数。
一个sub_match就是一个子串,它从std::pair<BidiIterator, BidiIterator>继承而来,这个迭代器pair里的first和second分别指向了这个子串开始和结尾所在位置。同时,sub_match又提供了str(),length()方法来返回整个子串。
regex_match只验证是否完全匹配,如果想从一大串字符串里找出匹配的一小段字符串(比如从网页文件里找超链接),这时就要使用regex_search了。
下面这段代码从szStr中找数字
{ //查找 boost::cmatch mat; boost::regex reg( "//d+" ); //查找字符串里的数字 if(boost::regex_search(szStr, mat, reg)) { cout << "searched:" << mat[0] << endl; } }
regex_replace提供了简便的方法来部分替换源字符串
正则表达式中,使用$1~$9(或/1~/9)表示第几个子串,$&表示整个串,$`表示第一个串,$'表示最后未处理的串。
{ //替换1,把上面的HTTP的URL转成FTP的 boost::regex reg( szReg ); string s = boost::regex_replace( string(szStr), reg, "ftp://$2$5"); cout << "ftp site:"<< s << endl; }
正则表达式中,使用(?1~?9新字串)表示把第几个子串替换成新字串