第115讲 boost::algorithm::string

虽然我们通过一个简单的MString来介绍了一些关于字符串操作的方式,那么我们是不是就没有必要介绍boost的字符串操作呢?当然不是了,毕竟MString只是为了平时使用设计的一个小东西,并没有针对大块字符串进行优化,所以,当我们处理大量数据的时候我们大概还是得优先选择更加高效的方式来处理,就比如说,在我们连续使用operator+=来对字符串连接的时候,当数量上百万以上时,我们会发现strcat的效率远远低于标准库string的operator+=,而对于拷贝来说,MString的效率又远远高于std::string,所以很多时候我们还是得看取舍,当我们要操作的字符串数据在几M之内,那么选择MString会比较好操作一些,如果数据量已经达到数百M以上,还是使用标准库的吧,因为标准库的对内存操作有优化,而MString只是简单的使用new来操作内存,所以在内存的需求量很大的时候,new不一定能够获取我们所需要的内存。那么,问题来来,我们是否要解决这个问题呢?嗯,如果从库的开发者角度来说是需要的(其实当初本来就打算使用std::alloc分配器的),但对我们来说就没有去专研这些比较底层的东西来。

那么,我们这一讲所说的正是对标准库string进行优化的一些操作算法,这些算法全都在boost::algorithm之中,如果我们想要使用他,就要包含boost/algorithm/string.hpp 文件。


上一讲的内存,大家都认为内容太过多来一些,那么,现在我们可以少说一些。


首先我们来看看查找一簇函数的使用的方法。


关于boost的查找一簇函数和我们平惯用的查找还是有区别的,通常我们的查找使用size_t作为返回值,如果查找就返回查找到的开始位置,如果查找不到就直接返回-1,对于size_t来说,-1是一个很大的正整数,和返回size_t相比,boost的是基于范围的返回,其实简单点说这个范围有点pair的味道,但他更像一个系列。


//=============================================

std::string str("

Hello World"

);

auto pos= boost::algorithm::find_first(str, "

Hallo"

);

if (pos.begin() != pos.end()){

std::string str2(pos.begin(), pos.end());

std::cout <<str2 <<std::endl;

}

else{

std::cout <<"

not find …. "

<<std::endl;

}


这里的pos的类型就是iterator_range,为来简便所以这里使用auto了。

//============================================


和MString提供的操作一样,查找一簇函数包含来众多:


//============================================

boost::algorithm::find_all // 查找所有


// 使用

std::string str("

Hello World Hello"

);

std::vector<std::string>v;

// 用来储存查找到的结果

boost::algorithm::find_all(v, str, "

Hello"

);


boost::algorithm::find_nth // 查找第N次出现的位置

该函数和MString的倒是有点区别,因为MString是从1开始,这个函数是从0开始计数的

就像下面一样我们查找第二次出现的那么就是1

auto pos2 = boost::algorithm::find_nth(str, "

Hello"

, 1);

if (pos2.begin() != pos2.end()){

std::string str2(pos2.begin(), pos2.end());

std::cout <<str2 <<std::endl;

}

else{

std::cout <<"

not find …. "

<<std::endl;

}


boost::algorithm::find_head 该函数的作用是将前面的几个字符串提取出来的,所以严格意义上来算不算真正的查找。

auto pos3 = boost::algorithm::find_head(str, 5);

// 将前面5个字节提取出来

if (pos3.begin() != pos3.end()){

std::string str2(pos3.begin(), pos3.end());

std::cout <<str2 <<std::endl;

}

else{

std::cout <<"

not find …. "

<<std::endl;

}


boost::algorithm::find_tail 该函数和find_head对应,提取的是最后的几个字节

auto pos4 = boost::algorithm::find_tail(str, 4);

if (pos4.begin() != pos4.end()){

std::string str2(pos4.begin(), pos4.end());

std::cout <<str2 <<std::endl;

}

else{

std::cout <<"

not find …. "

<<std::endl;

}


boost::algorithm::find_token,这个函数是按照给定条件来查找

auto pos5 = boost::algorithm::find_token(str, [](char s){
return s >70;

});

if (pos5.begin() != pos5.end()){

std::string str2(pos5.begin(), pos5.end());

std::cout <<str2 <<std::endl;

}

else{

std::cout <<"

not find …. "

<<std::endl;

}

//========================================


对于查找一簇来说,除来find_head和find_tail之外,上面的几个函数都有一个以i开头的版本,例如ifind_first,ifind_last,ifind_nth,ifind_all,这些函数的功能是不区分大小写的查找。

对这些函数,其实熟悉来后使用起来都很简单,唯一需要注意的就是find_token,因为他有第三个参数,这个参数有默认值boost::algorithm::token_compress_off,这个默认值的作用是需要返回满足我们给定条件的第一个字符的位置,所以当我们想要一个连续满足我们给定条件的字符串时,应当指定第三个参数为boost::algorithm::token_compress_on。就比如上面我们的例子中,现在的结果是H,因为H本身就大于70,所以在第一个满足之后就返回来,但当我们将第三个参数指定为boost::algorithm::token_compress_on时,返回的就是Hello,因为Hello后面的空格小于70,所以条件判断结束。


ok,这一讲我们就到此结束吧。

第115讲  boost::algorithm::string

//===========================================

回复D或者d查看目录,回复阿拉伯数字查看相应章节


原文始发于微信公众号(

C/C++的编程教室

):第115讲 boost::algorithm::string

|

发表评论