lexical_const
lexical_const库进行“字面值”的转换,类似C中的atoi函数,可以进行字符串与整数、浮点数之间的字面转换,使用时需要包含头文件<boost/lexical_cast.hpp>。
#include <iostream>
#include <string>
#include <boost/lexical_cast.hpp>
using namespace std;
using namespace boost;
int main()
{
/* 基本用法 */
int x = lexical_cast<int>("10"); //字符串->整数
string str = lexical_cast<string>(123); //整数->字符串
string str2 = lexical_cast<string>(0x10); //16进制整数->字符串
cout << x << ", " << str << ", " << str2 << endl;
/* 错误处理 */
try {
cout << lexical_cast<int>("0x10"); //要转换成数字的字符串中只能有数字和小数点
} catch (bad_lexical_cast &e) {
cout << "error: " << e.what() << endl;
}
if (!conversion::try_lexical_convert("0x10", x)) //判断是否能转换成功,避免抛出异常
cout << "不能将'0x10'转换成数字\n";
}
输出:
10, 123, 16
error: bad lexical cast: source type value could not be interpreted as target
不能将'0x10'转换成数字
error: bad lexical cast: source type value could not be interpreted as target
不能将'0x10'转换成数字
string_ref
在C++中处理字符串的基本工具是标准字符串std::string,但构造一个std::string成本很高,因为它必须完全持有字符串的内容,极端的时候会有很高的内存拷贝代价是,影响程序效率。使用const std::string&可以避免一些问题,但它在处理C字符串、提取子串时却又无能为力。总而言之,std::string显得有些”重“,我们需要一种更”轻“的字符串工具。
boost.string_ref就是这样一种轻量极的字符串,它只持有字符串的引用,没有内存拷贝成本,所以运行效率很高,是更好的const std::string&。它的工作原理很简单,它不拷贝字符串,所以也就不分配内存,只用两个成员变量ptr_和len_标记字符串的起始位置和长度,这样就实现了字符串的表示。但需要注意的是,我们只能像const std::string&那样去观察字符串而无法修改字符串。使用时需要包含头文件<boost/utility/string_ref.hpp>。
#include <iostream>
#include <string>
#include <string.h>
#include <boost/utility/string_ref.hpp>
using namespace std;
using namespace boost;
int main()
{
const char *ch = "hello world";
string str(ch); //标准字符串,有拷贝成本
string_ref s1(ch); //字符数组构造,零拷贝
string_ref s2(str); //标准字符串构造,零拷贝
/* 截取字符串 */
string_ref s3(ch, 4);
string str2 = str.substr(0, 4);
/* 赋值 */
string_ref s4, s5;
s4 = ch;
s5 = str;
/* 转换为标准字符串,获得一个拷贝 */
string str3 = s1.to_string();
/* 当做标准字符串使用(修改操作除外) */
if (s1.size() == strlen(ch))
cout << "s1.size() == strlen(ch)\n";
for(auto &x : s1)
{
cout << x ;
}
cout << endl;
if (s1.front() == 'H')
cout << "s1.front() == 'A'\n";
if (s1.find('o') == 4)
cout << "s1.find('o') == 4)\n";
auto substr = s1.substr(1, 4);
cout << "s1.substr(1, 4) = " << substr << endl;
/* 调整string_ref内部的字符串指针和长度,达到变动字符串引用的目的 */
s1.remove_prefix(2); //删除前两个字符
cout << "now: s1 = " << s1 << endl;
s1.remove_suffix(2); //删除后两个字符
cout << "now: s1 = " << s1 << endl;
}
输出:
s1.size() == strlen(ch)
hello world
s1.find('o') == 4)
s1.substr(1, 4) = ello
now: s1 = llo world
now: s1 = llo wor
hello world
s1.find('o') == 4)
s1.substr(1, 4) = ello
now: s1 = llo world
now: s1 = llo wor
string_algo
string_algo库是一个非常全面的字符串算法库,提供了大量的字符串操作函数,如大小写无关比较、修剪、特定模式的子串查找等。使用时需要包含头文件<boost/algorithm/string.hpp>。
string_algo库中的算法命名遵循了标准库的惯例,算法名均是小写形式,并使用不同的词缀来区分不同的版本,命名规则是:
前缀i
:
大小写不敏感(忽略大小写),否则是大小写敏感的;
后缀_copy
:
不变动输入,返回处理结果的拷贝,否则在原地址上处理。
后缀_if
:
需要一个作为判断式的谓词函数对象,否则使用默认的判断准则。
#include <iostream>
#include <string>
#include <deque>
#include <list>
#include <boost/utility/string_ref.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/assign.hpp>
using namespace std;
using namespace boost;
int main()
{
/* 大小写转换 */
string str("HELLO world\n");
cout << to_upper_copy(str); //返回大写后的拷贝
cout << str; //原字符串不改变
to_lower(str); //字符串小写
cout << str; //原字符串被改变
cout << endl;
/* 判断式 */
str = "hello wOrLd";
if (iends_with(str, "world")) //大小写无关检测后缀
cout << "iends_with(str, 'world'): true\n";
if (!ends_with(str, "world")) //大小写敏感检测后缀
cout << "ends_with(str, 'world'): false\n";
if (starts_with(str, "Pow")); //检测前缀
cout << "start_with(str, 'hello'): true\n";
if (contains(str, "ll")) //测试包含关系
cout << "contains(str, 'll'): true\n";
string str2 = to_lower_copy(str);
if (iequals(str, str2)) //大小写无关判断相等
cout << "iequals(str, str2): true\n";
string str3("hello cpp");
if (ilexicographical_compare(str3, str)) //大小写无关比较
cout << "ilexicographical_compare(str3, str): true\n";
if (all("hello", is_lower())) //检测字串均小写(all用来检测一个字符串中的所有元素是否满足指定的判断式)
cout << "all('hello', is_lower()): true\n";
cout << endl;
/* 分类和修剪 */
str = " hello boost ";
cout << trim_copy(str); //删除两端的空格
cout << trim_left_copy(str); //删除左端的空格
trim_right(str); //删除右端的空格
cout << str;
str2 = "2016 Happy new Year!!!";
cout << trim_left_copy_if(str2, is_digit()); //删除左端的数字
cout << trim_right_copy_if(str2, is_punct()); //删除右端的标点
cout << trim_copy_if(str2, is_punct() || is_digit() || is_space()); //删除两端的标点、数字和空格
/* 查找 */
str = "Long long ago, there was a king.";
iterator_range<string::iterator> rge; //迭代器区间
rge = find_first(str, "long"); //找第一次出现
cout << "find_first: " << rge.begin() - str.begin() << endl;
rge = ifind_first(str, "long"); //大小写无关找第一次出现
cout << "ifind_first: " << rge.begin() - str.begin() << endl;
rge = find_nth(str, "ng", 2); //找第三次出现
cout << "find_nth: " << rge.begin() - str.begin() << endl;
rge = find_head(str, 4); //取前4个字符
cout << "find_head: " << rge << endl;
rge = find_tail(str, 5); //取末尾5个字符
cout << "find_tail: " << rge << endl;
rge = find_first(str, "samus");
if (rge.empty() && !rge) //找不到
cout << "find_first: " << "找不到\n\n";
/* 替换和删除 */
str = "Samus beat the monster.\n";
cout << replace_first_copy(str, "Samus", "samus"); //替换"Samus"在str中的第一次出现
replace_last(str, "beat", "kill"); //替换"beat"在str中的最后一次出现
cout << str;
replace_tail(str, 9, "ridley.\n"); //替换str的末尾9个字符
cout << str;
cout << ierase_all_copy(str, "samus"); //删除"samus"在str中的所有出现
cout << replace_nth_copy(str, "l", 1, "L"); //替换"l"在str中的第1次出现
cout << erase_tail_copy(str, 8); //删除str的末尾8个字符
cout << endl << endl;
/* 分割
* 容器的元素类型必须是string或者iterator_range<string::iterator>
* 容器可以是vector、list、deque等标准容器
*/
str = "Samus,Link.Zelda::Mario-Luigi+zelda";
deque<string> d;
ifind_all(d, str, "zELDA"); //大小无关分割字符串
for (auto x : d)
cout << "["<< x << "] ";
cout << endl;
list<iterator_range<string::iterator> > 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); //token_compress_on表示当两个分隔符连续出现时将被视为一个
for (auto x : l)
cout << "["<< x << "]";
cout << endl << endl;
/* 合并 */
vector<string> v = assign::list_of("Samus")("Link")("Zelda")("Mario");
cout << join(v, "+") << endl; //简单合并
cout << join_if(v, "**", //带谓词的合并
[](string_ref s) //lambda表达式
{ return contains(s, "a"); } //包含字符'a'
);
cout << endl << endl;
/* 查找(分割)迭代器 */
str = "Samus||samus||mario||||Link";
typedef find_iterator<string::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::iterator> string_split_iterator;
string_split_iterator p, endp;
for (p = make_split_iterator(str, first_finder("||", is_iequal())); p != endp; ++p)
cout << "[" << *p << "]";
cout << endl;
}
输出:
HELLO WORLD
HELLO world
hello world
iends_with(str, 'world'): true
ends_with(str, 'world'): false
start_with(str, 'hello'): true
contains(str, 'll'): true
iequals(str, str2): true
ilexicographical_compare(str3, str): true
all('hello', is_lower()): true
hello boosthello boost hello boost Happy new Year!!!2016 Happy new YearHappy ne
w Yearfind_first: 5
ifind_first: 0
find_nth: 29
find_head: Long
find_tail: king.
find_first: 找不到
samus beat the monster.
Samus kill the monster.
Samus kill the ridley.
kill the ridley.
Samus kilL the ridley.
Samus kill the
[Zelda] [zelda]
[Samus][Link][Zelda][][Mario][Luigi][zelda]
[Samus,Link][Zelda][Mario][Luigi+zelda]
Samus+Link+Zelda+Mario
Samus**Zelda**Mario
[Samus][samus]
[Samus][samus][mario][][Link]
HELLO world
hello world
iends_with(str, 'world'): true
ends_with(str, 'world'): false
start_with(str, 'hello'): true
contains(str, 'll'): true
iequals(str, str2): true
ilexicographical_compare(str3, str): true
all('hello', is_lower()): true
hello boosthello boost hello boost Happy new Year!!!2016 Happy new YearHappy ne
w Yearfind_first: 5
ifind_first: 0
find_nth: 29
find_head: Long
find_tail: king.
find_first: 找不到
samus beat the monster.
Samus kill the monster.
Samus kill the ridley.
kill the ridley.
Samus kilL the ridley.
Samus kill the
[Zelda] [zelda]
[Samus][Link][Zelda][][Mario][Luigi][zelda]
[Samus,Link][Zelda][Mario][Luigi+zelda]
Samus+Link+Zelda+Mario
Samus**Zelda**Mario
[Samus][samus]
[Samus][samus][mario][][Link]