5.删除、替换
查找到子串位置,可以将子串删除,替换成另一个子串。下面仅列出主要函数的声明。
(1)删除
//删除第一个子串
void erase_first(SequenceT& Input, const RangeT& Search);
//删除最后一个子串
void erase_last(SequenceT& Input, const RangeT& Search);
//删除第N个子串(N从0开始)
void erase_nth(SequenceT& Input, const RangeT& Search, int Nth);
//删除母串中所有的指定子串
void erase_all(SequenceT& Input, const RangeT& Search);
//删除母串头部指定个字符
void erase_head(SequenceT& Input, int N);
//删除母串尾部指定个字符
void erase_tail(SequenceT& Input, int N);
(2)替换
将第一个子串Search替换为Format
void replace_first(SequenceT& Input
, const RangeT& Search, const RangeT& Format);
将最后一个子串Search替换为Format
void replace_last(SequenceT& Input
, const RangeT& Search, const RangeT& Format);
替换第N个子串Search(N从0开始)为Format
void replace_nth(SequenceT& Input
, const RangeT& Search, int Nth, const RangeT& Format);
将母串中所有的子串Search替换成Format
void replace_all(SequenceT& Input
, const RangeT& Search, const RangeT& Format);
将母串头部指定个字符替换为Format
void replace_head(SequenceT& Input, int N, const RangeT& Format);
将母串尾部指定个替换为Format
void replace_tail(SequenceT& Input, int N, const RangeT& Format);
其他还有不区分大小写的版本,以及不直接修改原串的 _copy版本
6.分割与合并
有一个字符串内容为“56, 37, 120, 90”,我们希望得到中间的4个数字求和,这就需要将数字从字符串中“抠”出来。若发现数字之间使用英文逗号区分,如果让母串以该字符拆分,就基本可以达成目标。boost::algorithm::split 正好派上用场。
SequenceSequenceT& split(SequenceSequenceT& Result
, RangeT& Input
, PredicateT pred
, token_compress_mode_type type = token_compress_off)
//split将Input(母串)进行切分,切分依据是“Pred”,
//Pred正是前面我们提过的“判断是”:
//切分结果放入Result中(并返回)
void test_split()
{
//37和120之间使用";"分隔
string s = "56, 37; 120, 90";
vector <string> v;
//多添加一种分隔符
boost::algorithm::
split(v, s, boost::algorithm::is_any_of(",;"));
int sum = 0;
for(vector <string>::const_iterator it = v.begin()
; it != v.end(); ++it)
{
//去前后空格
string tmp = boost::algorithm::trim_copy(* it);
//转换string为int。同样使用boost的方法,后面将学习
int a = boost::lexical_cast<int> (tmp);
cout << a << ",";
sum += a;
}
cout << "sum = " << sum << endl;
}
如果存在多种分隔符,可以在 is_any_of 中一一添加:
//37和120之间使用";"分隔
string s = "56, 37; 120, 90";
...
//多添加一种分隔符
split(v, s, is_any_of(",;"));
注意:使用 split 拆分复杂字符串时,分隔结果不一定就是我们直觉推想的结果,因此实际处理时需要小心印证,再对拆分结果做处理。
最后,split 还有一个“token_compress_mode_type”类型的参数,它表明如果分割符连续挨在一起,是否要跳过中间空的内容,设母串是“123, 456, 7”,若 type 取 token_compress_on,则空子串被抛弃,默认值是 token_compress_off。
【课堂作业】:根据子串切分母串
split只能处理单一字符,通过使用 wstring 以便使用汉字单字切分,仍然处理不了按多个字符的子串切分,比如母串是:123->456->789,希望用“->”切分。请使用前面学习过的字符串算法,实现这一功能。
join是split的逆运算。它将存储在容器中的字符串,依序拼接成一个新串,并且可以指定连接的分隔符;它倒是可以方便地支持分隔符是一个子串。
下面将前例的“test_split()”改名为“test_split_join()”,然后将前面切分得到的v中的子串,再连成一个长串:
void test_split_join()
{
...
cout << str_algo::join(v, "==>") << endl;
}
join还有一个版本,叫“ join_if ”,它允许提供一个判断式,以便设置要合并的子串的条件。比如可以要求,仅当子串转换成整数后,值大于50的才参与合并:
bool big_then_50(string const& s)
{
int a = boost::lexical_cast<int>(str_algo::trim_copy(s));
return a > 50;
}
void test_split_join()
{
...
cout << str_algo::join(v, "==>") << endl;
cout << str_algo::join_if(v, "==>", big_then_50) << endl;
}