下面的 代码是 boost 正则匹配后 取出 匹配字符 //提取子串
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)
{
//这里面的要怎么写 怎么读取出匹配的字符,别人说是在 *itr 或mat[0]中,但这两个数据都定义是模板。我用AfxMessageBox()把这两个值输出 都报错,说是类型不对,我是VS2010 怎么样才能正常输出 ,谢谢大家了。可以付费 我的QQ 29 29 24290
}
}
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)
{
//这里面的要怎么写 怎么读取出匹配的字符,别人说是在 *itr 或mat[0]中,但这两个数据都定义是模板。我用AfxMessageBox()把这两个值输出 都报错,说是类型不对,我是VS2010 怎么样才能正常输出 ,谢谢大家了。可以付费 我的QQ 29 29 24290
}
}
--------------------分割线---------------------------boost::regex的用法 * boost::regex的用法 bool validate_card_format(const std::string s)
{
static const boost::regex e("(\\d{4}[- ]){3}\\d{4}");
return regex_match(s, e);
} * boost::regex的默认正则表达式语法是perl语法 boost::regex支持perl regular表达式、POSIX-Extended regular表达式和POSIX-Basic Regular表达式,但默认的表达式语法是perl语法,如果要使用其余两种语法需要在构造表达式的时候明确指定。 例如,下面两种方法效果相同
// e1 is a case sensitive Perl regular expression:
// since Perl is the default option there's no need to explicitly specify the syntax used here:
boost::regex e1(my_expression);
// e2 a case insensitive Perl regular expression:
boost::regex e2(my_expression, boost::regex::perl|boost::regex::icase); * perl正则表达式语法 perl正则表达式语法可参见《perl语言入门》第7、8、9章或boost的文档。这里列出的语法是不全面的。 . 任意字符;使用match_no_dot_null标志时不匹配NULL字符; 使用match_not_dot_newline时不匹配换行字符 ^ 匹配行的开始
$ 匹配行的结束
* 重复零次或则更多,例如a*b可匹配b,ab,aab,aaaaaaab
+ 重复一次以上,例如a+b可匹配ab,aab,aaaaaaaab。但不能匹配b了
? 零次或则一次,例如ca?b匹配cb,cab但不匹被caab
a{n} 匹配字符'a'重复n次
a{n,},字符a重复n次以上(含n次)
a{n,m} a重复n到m次(含) *? 匹配前一个原子零次以上
+? 匹配前一个原子一次以上
?? 匹配前一个原子零次以上
{n,}? 匹配前一个原子n次以上(含)
{n,m? 匹配前一个原子n到m次(含) | 或操作,例如ab(d|ef)匹配abd或则abef
[] 字符集操作,例如[abc]将匹配任何单个字符'a','b','c'
[a-d],表示a、b、c、d
^否操作,例如[^a-c]表示a至c之外的所有字符 * boost::regex对unicode编码的支持 boost::regex使用ICU来实现对unicode及unicode变种的支持,这需要在编译boost的时候指出是否使用ICU 以及ICU所在的目录。否则编译出来的boost::regex不支持unicode编码。其中boost::wregex支持unicode编码的搜索,如果要搜索UTF-8、UTF-16、UFT-32编码的字符串,则要用boost::u32regex。注意boost::wregex只能支持 unicode编码,不能支持uft编码。 * 搜索时如何忽略大小写 如果要在搜索时忽略大小写(即大小写不敏感),则要用到表达式选项boost::regex::icase,例如: boost::regex e2(my_expression, boost::regex::perl|boost::regex::icase);
-----------------------------------------------
boost::regex类为C++提供了完整的正则表达式支持,并且已被接收为C++0x标准库。它同时也在Boost库中扮演着极重要的角色,不少Boost子库都需要它的支持,有不少人甚至就是为了它才下载使用Boost的。
注意使用Boost.Regex需要预先编译
完整编译请参考本站编译Boost的文章
如果只要编译Regex库,有两种方法(参考链接): 1. 在Boost根目录下运行bjam --toolset=<编译器名> --with-regex 其它参数
2. 到<boost>\libs egex\build里,找到对应编译器的makefile,然后make -f xxxx.mak 使用
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框架来做这个实验,花一样时间学两样啊~~ 1. #include <iostream>
2. #include <boost/regex.hpp>
3.
4. using namespace std;
5. int main(int argc, char* argv[])
6. { //( 1 ) (( 3 ) 2 )(( 5 )4)( 6 )
7. //(\w+)://((\w+\.)*\w+)((/\w*)*)(/\w+\.\w+)?
8. //^协议://网址(x.x...x)/路径(n个\字串)/网页文件(xxx.xxx)
9. const char *szReg = "(\\w+)://((\\w+\\.)*\\w+)((/\\w*)*)(/\\w+\\.\\w+)?";
10. const char *szStr = "http://www.cppprog.com/2009/0112/48.html";
11.
12. //练习代码...
13.
14.
15. cin.get(); //暂停
16. } #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(); //暂停
}
1.字符串匹配
要确定一行字符串是否与指定的正则表达式匹配,使用regex_match。
下面这个代码可以验证szStr字串(定义在上面)是否与szReg匹配。 1. { //字符串匹配
2. boost::regex reg( szReg );
3. bool r=boost::regex_match( szStr , reg);
4. assert(r); //是否匹配
5. } { //字符串匹配
boost::regex reg( szReg );
bool r=boost::regex_match( szStr , reg);
assert(r); //是否匹配
}
boost::regex的构造函数中还可以加入标记参数用于指定它的行为,如: 1. //指定使用perl语法(默认),忽略大小写。
2. boost::regex reg1( szReg, boost::regex::perl|boost::regex::icase );
3. //指定使用POSIX扩展语法(其实也差不多)
4. boost::regex reg2( szReg, boost::regex::extended ); //指定使用perl语法(默认),忽略大小写。
boost::regex reg1( szReg, boost::regex::perl|boost::regex::icase );
//指定使用POSIX扩展语法(其实也差不多)
boost::regex reg2( szReg, boost::regex::extended ); 下面这个代码不仅验证是否匹配,而且可以从中提取出正则表达式括号对应的子串。 1. { //提取子串
2. boost::cmatch mat;
3. boost::regex reg( szStr );
4. bool r=boost::regex_match( szStr, mat, reg);
5. if(r) //如果匹配成功
6. {
7. //显示所有子串
8. for(boost::cmatch::iterator itr=mat.begin(); itr!=mat.end(); ++itr)
9. {
10. // 指向子串对应首位置 指向子串对应尾位置 子串内容
11. cout << itr->first-szStr << ' ' << itr->second-szStr << ' ' << *itr << endl;
12. }
13. }
14. //也可直接取指定位置信息
15. if(mat[4].matched) cout << "Path is" << mat[4] << endl;
16. } { //提取子串
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()方法来返回整个子串。
2.查找字符串
regex_match只验证是否完全匹配,如果想从一大串字符串里找出匹配的一小段字符串(比如从网页文件里找超链接),这时就要使用regex_search了。
下面这段代码从szStr中找数字 1. { //查找
2. boost::cmatch mat;
3. boost::regex reg( "\\d+" ); //查找字符串里的数字
4. if(boost::regex_search(szStr, mat, reg))
5. {
6. cout << "searched:" << mat[0] << endl;
7. }
8. } { //查找
boost::cmatch mat;
boost::regex reg( "\\d+" ); //查找字符串里的数字
if(boost::regex_search(szStr, mat, reg))
{
cout << "searched:" << mat[0] << endl;
}
}
3.替换
regex_replace提供了简便的方法来部分替换源字符串
正则表达式中,使用$1~$9(或\1~\9)表示第几个子串,$&表示整个串,$`表示第一个串,$'表示最后未处理的串。 1. { //替换1,把上面的HTTP的URL转成FTP的
2. boost::regex reg( szReg );
3. string s = boost::regex_replace( string(szStr), reg, "ftp://$2$5");
4. cout << "ftp site:"<< s << endl;
5. } { //替换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新字串)表示把第几个子串替换成新字串 1. { //替换2,使用format_all参数把<>&全部转换成网页字符
2. string s1 = "(<)|(>)|(&)";
3. string s2 = "(?1<)(?2>)(?3&)";
4. boost::regex reg( s1 );
5. string s = boost::regex_replace( string("cout << a&b << endl;"), reg, s2, boost::match_default | boost::format_all);
6. cout << "HTML:"<< s << endl;
7. } { //替换2,使用format_all参数把<>&全部转换成网页字符
string s1 = "(<)|(>)|(&)";
string s2 = "(?1<)(?2>)(?3&)";
boost::regex reg( s1 );
string s = boost::regex_replace( string("cout << a&b << endl;"), reg, s2, boost::match_default | boost::format_all);
cout << "HTML:"<< s << endl;
}
--------------------分割线-------------------------------
9. {
10. // 指向子串对应首位置 指向子串对应尾位置 子串内容
11. cout << itr->first-szStr << ' ' << itr->second-szStr << ' ' << *itr << endl;
12. }
13. }
14. //也可直接取指定位置信息
15. if(mat[4].matched) cout << "Path is" << mat[4] << endl;
16. }
---------------------分割线---------------------
既然能用cout输出“itr->first-szStr”等内容,
就应该可以用
CString 的Format 格式化输出,
剩下的就是找找每个变量的数据类型了。