string_algo
string_algo被设计用于处理字符串,然而处理对象并不一定是string或basic_string
string_algo库位于名字空间boost::algorithm,但被using语句引入到了名字空间boost,为了使用它,需要包含头文件
#include
using namespace boost;
string_algo库提供的算法共分五大类:
string_algo库中的算法命名遵循了标准库的惯例,算法名均为小写形式,并使用不同的词缀来区分不同的版本,命名规则:
大小写转换
#include
#include
#include
using namespace boost;
using namespace std;
int main()
{
string str("I Don't Know.\n");
//转换为大写
cout << to_upper_copy(str) << endl;
//原字符串不变
cout << str << endl;
//转换我小写
to_lower(str);
//原字符串被改变
cout << str << endl;
getchar();
return 0;
}
运行结果:
判断式(算法)
主要检测两个字符串之间的关系,包含以下几种:
除了all,这些算法都有 i 前缀的版本。由于它们不变动字符串,因此没有_copy版本。
用法:
#include
#include
#include
using namespace boost;
using namespace std;
int main()
{
string str("Power Bomb");
//大小写无关检测
assert(iends_with(str, "bomb"));
//大小写敏感检测后缀
assert(!ends_with(str, "bomb"));
//检测前缀
assert(starts_with(str, "Pow"));
//检测包含关系
assert(contains(str, "er"));
//转换小写
string str2 = to_lower_copy(str);
//大小写转换无关判断
assert(iequals(str, str2));
string str3("power suit");
//大小写无关比较
assert(ilexicographical_compare(str, str3));
//检测字符串均小写
assert(all(str2.substr(0, 5), is_lower()));
getchar();
return 0;
}
判断式(函数对象)
允许对不同类型的参数进行比较,并提供大小写无关的形式。
用法:
#include
#include
#include
using namespace boost;
using namespace std;
int main()
{
string str1("Samus");
string str2("samus");
assert(!is_equal()(str1, str2));
assert(is_less()(str1, str2));
getchar();
return 0;
}
注意:调用的两个括号,第一个括号调用了函数对象的构造函数,产生一个对象,第二个才是函数调用。
分类
用于检测一个字符是否符合某种特性。
修剪
string_algo提供了三个修剪算法:trim_left、trim_right和trim。
修剪算法可以删除字符串开头或结尾部分的空格,它有_if 和_copy 两种后缀,因此每个算法有四个版本。_if版本接受一个判断式IsSpace,将所有被判定为空格(IsSpace(c) == true)的字符删除。
用法:
#include
#include
#include
#include
using namespace boost;
using namespace std;
int main()
{
format fmt("|%s|\n");
string str = " samus aran ";
//删除两端的空格
cout << fmt % trim_copy(str) << endl;
//删除左端空格
cout << fmt % trim_left_copy(str) << endl;
//原地删除右端空格
trim_right(str);
cout << fmt % str << endl;
string str2 = "2020 Happy new Year!!!";
//删除左端的数字
cout << fmt % trim_left_copy_if(str2, is_digit());
//删除右端的标点
cout << fmt % trim_right_copy_if(str2, is_punct());
//删除两端的标点、数字和空格
cout << fmt % trim_copy_if(str2, is_punct() || is_digit() || is_space());
getchar();
return 0;
}
运行结果:
查找
string_algo算法它不返回一个迭代器(查找到的位置),而使用了boost.range库的iterator_range返回查找到的整个区间,获得了更多的信息,便于算法串联和其他处理。
iterator_range 概念上类似 std::pair
这些算法都不变动字符串,因此没有_copy后缀版本,但其中前三个算法有 i 前缀的版本。
使用:
#include
#include
#include
#include
using namespace boost;
using namespace std;
int main()
{
format fmt("|%s| . pos = %d\n");
string str = "Long long ago , there was a king.";
//迭代器区间
iterator_range rge;
//查找第一次出现
rge = find_first(str, "long");
cout << fmt % rge % (rge.begin() - str.begin()) << endl;
//大小写无关找第一次出现
rge = ifind_first(str, "long");
cout<< fmt % rge % (rge.begin() - str.begin()) << endl;
//找第三次出现
rge = find_nth(str, "ng", 2);
cout << fmt % rge % (rge.begin() - str.begin()) << endl;
//取前4个字符
rge = find_head(str, 4);
cout << fmt % rge % (rge.begin() - str.begin()) << endl;
//取末尾5个字符
rge = find_tail(str, 5);
cout << fmt % rge % (rge.begin() - str.begin()) << endl;
//找不到
rge = find_first(str, "samus");
assert(rge.empty() && !rge);
getchar();
return 0;
}
替换与删除
替换、删除操作与查找算法非常接近,是在查找到结果后再对字符串进行处理。
前八个算法每个都有前缀 i 、后缀_copy 和组合,有4个版本,后四个则只有后缀_copy两个版本。
用法:
#include
#include
#include
#include
using namespace boost;
using namespace std;
int main()
{
string str = "Samus beat the monster.\n";
//替换第一次出现的地方
cout << replace_first_copy(str, "Samus", "samus") << endl;
//替换在最后一次出现的地方
replace_last(str, "beat", "kill");
cout << str << endl;
//替换末尾9个字符
replace_tail(str, 9, "ridley.\n");
cout << str << endl;
//不分大小写删除出现的所有位置
cout << ierase_all_copy(str, "samus") << endl;
//找到r字符出现第1次 将 r 替换为 L
cout << replace_nth_copy(str, "r", 0, "L");
//删除尾部8个字符
cout << erase_tail_copy(str, 8);
getchar();
return 0;
}
分割
用法:
#include
#include
#include
#include
using namespace boost;
using namespace std;
int main()
{
string str = "A,B.C::Dd-Ee+DD";
deque d;
//大小写无关分割字符串
ifind_all(d, str, "Dd");
//遍历deque里字符串
for (auto x : d)
{
cout << "[" << x << "]";
}
cout << endl;
//存储range对象
list < iterator_range> l;
//使用标点分割
split(l, str, is_any_of(",.:-+"));
//遍历
for (auto x : l)
{
cout << "[" << x << "]";
}
cout << endl;
l.clear();
split(l, str, is_any_of(".:-"), token_compress_on);
for (auto x : l)
{
cout << "[" << x << "]";
}
cout << endl;
getchar();
return 0;
}
运行截图:
合并
join算法是分割算法的逆运算,它把存储在容器中的字符串连接成一个新的字符串,并且可以指定连续的分隔符。
join有一个后缀 _if 的版本。
用法:
#include
#include
#include
#include
#include
#include
using namespace boost;
using namespace std;
using namespace boost::assign;
int main()
{
//向vetor添加了4个字符
vector v = list_of("Samus")("Link")("Zelda")("Mario");
//用+合并它们
cout << join(v, "+") << endl;
//lambda表达式,判断包含a的 才合并
cout << join_if(v, "**", [](string_ref s)
{
return contains(s, "a");
});
getchar();
return 0;
}
运行结果:
查找(分割)迭代器
find_iterator 和 split_iterator
使用:
#include
#include
#include
#include
#include
#include
using namespace boost;
using namespace std;
int main()
{
string str("Samus | | samus | | mario | | | | Link");
//查找迭代器定义
typedef find_iterator string_find_iterator;
//声明变量
string_find_iterator pos, end;
//遍历
for (pos = make_find_iterator(str, first_finder("samus", is_iequal())); pos != end; ++pos)
{
cout << "[" << *pos << "]";
}
cout << endl;
//分割迭代器类型定义
typedef split_iterator string_split_iterator;
//声明变量
string_split_iterator p, endp;
for (p = make_split_iterator(str, first_finder(" | | ", is_equal())); p != endp; ++p)
{
cout << "[" << *p << "]";
}
cout << endl;
getchar();
return 0;
}
运行结果: