Boost之字符串

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'转换成数字


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


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]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值