关于Boost库的一些用法,涉及字符串的查找,判断,正则表达式,字符串分割,格式化输出。
#include "boost/algorithm/string.hpp"
#include "boost/algorithm/string/regex.hpp"
#include <locale>
#include <iostream>
#include <clocale>
#include <vector>
#include "boost/regex.hpp"
#include <boost/tokenizer.hpp>
#include <boost/format.hpp>
int main()
{
std::string s = "Boris Singchling";
//************ 用于 转换一个字符串为大小写形式
std::cout << boost::algorithm::to_lower_copy(s) << std::endl;
std::cout << boost::algorithm::to_upper_copy(s) << std::endl;
//*******从字符串中删除单独字母的函数,
std::cout << boost::algorithm::erase_first_copy(s, "i") << std::endl;//删除第一个I
std::cout << boost::algorithm::erase_nth_copy(s, "i", 0) << std::endl;//删除第一个I
std::cout << boost::algorithm::erase_last_copy(s, "i") << std::endl;//删除最后一个I
std::cout << boost::algorithm::erase_all_copy(s, "i") << std::endl;//删除所有I
std::cout << boost::algorithm::erase_head_copy(s, 5) << std::endl;//删除前五个字母
std::cout << boost::algorithm::erase_tail_copy(s, 5) << std::endl;//删除后五个字母
//*******可以用于在字符串中查找子串。
boost::iterator_range<std::string::iterator> r = boost::algorithm::find_first(s, "i225ng");
if (!r.empty())
std::cout << " r1" << r << std::endl;
r = boost::algorithm::find_first(s, "ris");
if (!r.empty())
std::cout << " r2" << r << std::endl;
//***********boost::algorithm::join() 接受一个字符串的容器 作为第一个参数, 根据第二个参数将这些字符串连接起来。
std::vector<std::string> v;
v.push_back("Boris");
v.push_back("Schaling");
std::cout << boost::algorithm::join(v, "&*") << std::endl;
//************供了使用字符串替代子串的函数
std::cout << boost::algorithm::replace_first_copy(s, "B", "D") << std::endl;
std::cout << boost::algorithm::replace_nth_copy(s, "i", 0, "D") << std::endl;
std::cout << boost::algorithm::replace_last_copy(s, "i", "D") << std::endl;
std::cout << boost::algorithm::replace_all_copy(s, "i", "D") << std::endl;
std::cout << boost::algorithm::replace_head_copy(s, 5, "DoAAA") << std::endl;
std::cout << boost::algorithm::replace_tail_copy(s, 8, "BecCCC") << std::endl;
//****************自动去除字符串中的空格或者字符串的结束符。 什么字符是空格取决于全局区域设置。
std::string s1 = "\t B oris Scha li ng \t";
std::cout << "." << boost::algorithm::trim_left_copy(s1) << "." << std::endl;
std::cout << "." << boost::algorithm::trim_right_copy(s1) << "." << std::endl;
std::cout << "." << boost::algorithm::trim_copy(s1) << "." << std::endl;
//****************接受一个附加的谓词参数,以决定函数作用于字符串的哪些字符。
std::string s2 = "--Boris--Sch--a-li--n+g--+";
std::cout << "." << boost::algorithm::trim_left_copy_if(s2, boost::algorithm::is_any_of("-")) << "." << std::endl;
std::cout << "." << boost::algorithm::trim_right_copy_if(s2, boost::algorithm::is_any_of("-")) << "." << std::endl;
std::cout << "." << boost::algorithm::trim_copy_if(s2, boost::algorithm::is_any_of("-")) << "." << std::endl;
std::cout << "." << boost::algorithm::trim_copy_if(s2, boost::algorithm::is_any_of("+")) << "." << std::endl;
std::string s3 = "123456789Boris Schaling123456789";
//去除左边
std::cout << "." << boost::algorithm::trim_left_copy_if(s3, boost::algorithm::is_digit()) << "." << std::endl;
//去除右边
std::cout << "." << boost::algorithm::trim_right_copy_if(s3, boost::algorithm::is_digit()) << "." << std::endl;
std::cout << "." << boost::algorithm::trim_copy_if(s3, boost::algorithm::is_digit()) << "." << std::endl;
//using algorithm::is_classified;
//using algorithm::is_space;
//using algorithm::is_alnum;
//using algorithm::is_alpha;
//using algorithm::is_cntrl;
//using algorithm::is_digit;
//using algorithm::is_graph;
//using algorithm::is_lower;
//using algorithm::is_upper;
//using algorithm::is_print;
//using algorithm::is_punct;
//using algorithm::is_xdigit;
//using algorithm::is_any_of;
//using algorithm::is_from_range;
//各种分割方式
//字符串切割函数。
std::string s4 = "Bo1ri5s 5 ds d Sch54al5ing";
std::cout << s4 << std::endl;
std::vector<std::string> v1;
//将字符串s 以空格切割,切割结果放到v中。
boost::algorithm::split(v1, s4, boost::algorithm::is_any_of("5"));
std::cout << v1.size() << std::endl;
boost::algorithm::split(v1, s4, boost::algorithm::is_upper());
std::cout << v1.size() << std::endl;
boost::algorithm::split(v1, s4, boost::algorithm::is_alnum());
std::cout << v1.size() << std::endl;
//*************** 正则表达式库 Boost.Regex
/*
. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线或汉字 等价于 '[^A-Z a-z 0-9_]'。
\s 匹配任意的空白符
\d 匹配数字
\b 匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束
+ 表示重复一次或者多次
* 表示重复零次或者多次
{n,m} 表示n 到 m 次
\\w+\\s\\w+ 形式(w+ 与w差不多 ,“+”意义:至少匹配一次)
*/
//匹配 任意字符 + 空格 + 字符,所以结果是“s S”
//boost::iterator_range<std::string::iterator> r1 = boost::algorithm::find_regex(s, boost::regex("\\w\\s\\w"));
//std::cout << r1 << std::endl;
//*************** 正则表达式库 Boost.Regex
//****函数 boost::regex_match() 用于字符串与正则表达式的比较。 在整个字符串匹配正则表达式时其返回值为 true 。
std::cout << "---------------regex_match---------------------" << std::endl;
std::cout << s << std::endl;
boost::regex expr("\\w+\\s\\w+");
std::cout << boost::regex_match(s, expr) << std::endl;
// ******************函数 boost::regex_search() 可用于在字符串中搜索正则表达式。
std::string hhdshj = "sdc_kshdch1fhfsdl bjsgdgcsd kjsgdfgsn uhfsgdbjk";
boost::regex expr4("(\\w+)\\s(\\w+)\\s(\\w+)");
boost::regex expr42("\\w+\\s\\w+\\s\\w+");
boost::smatch what;
if (boost::regex_search(hhdshj, what, expr42))//()可以把数组分开对比expr4使用,
{
std::cout << "ID_0 " << what[0] << std::endl;
std::cout << "ID_1 " << what[1] << " ID_2 " << what[2] << std::endl;
std::cout << "ID_1 " << what[3] << " ID_2 " << what[4] << std::endl;
}
//boost::regex_replace() 函数还需要一个格式参数,它决定了子串、匹配正则表达式的分组如何被替换。
/*std::string s = " Boris Schaling ";
//匹配任意空格*/
boost::regex expr1("\\s");
std::string fmt("_");
std::cout << boost::regex_replace(hhdshj, expr1, fmt) << std::endl;
std::cout << "----------------------------------------------------";
/*
格式参数可以访问由正则表达式分组的子串,这个例子正是使用了这项技术,
交换了姓、名的位置,于是结果显示为 kjsgdfgsn sdc_kshdch1fhfsdl uhfsgdbjk 。
*/
boost::regex expr2("(\\w+)\\s(\\w+)\\s(\\w+)");
std::string fmt1("\\3 \\1");
std::cout << boost::regex_replace(hhdshj, expr2, fmt1) << std::endl;
/*
将 boost::regex_constants::format_literal 标志作为第四参数传递给函数 boost::regex_replace() ,
从而抑制了格式参数中对特殊字符的处理。 因为整个字符串匹配正则表达式,
所以本例中经格式参数替换的到达的输出结果为 \2 \1。
*/
boost::regex expr3("(\\w+)\\s(\\w+)");
std::string fmt2("\\2 \\1");
std::cout << boost::regex_replace(s, expr3, fmt2, boost::regex_constants::format_literal) << std::endl;
/*
词汇分割器必须由类型为 std::string 的字符串初始化。通过使用 begin() 和 end() 方法,词汇分割器可以像容器一样访问。
boost::char_separator 类默认将 空格和标点符号 视为分隔符,所以本例显示的结果为 Boost 、 C 、 + 、 + 和 libraries 。
为了识别这些分隔符,boost::char_separator 函数调用了 std::isspace() 函数和 std::ispunct 函数()
Boost.Tokenizer 库会区分要隐藏的分隔符和要显示的分隔符。 在默认的情况下,空格会隐藏而标点符号会显示出来,
所以这个例子里显示了两个加号。
*/
std::cout << "----------------------------------------------------" << std::endl;
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
std::string s12 = "Boost C++ libraries";
tokenizer tok(s12);
for (tokenizer::iterator it = tok.begin(); it != tok.end(); ++it)
std::cout << *it << std::endl;
//如果不需要将标点符号作为分隔符,可以在传递给词汇分割器之前相应地初始化 boost::char_separator 对象。
/*
类 boost::char_separator 的构造函数可以接受三个参数,
第一个是必须的,它描述了需要隐藏的分隔符
第二个参数指定了需要显示的分隔符。
第三个参数决定了是否显示空的部分表达式。 如果连续找到两个分隔符(空格和标点符号),他们之间的部分表达式将为空。
在默认情况下,这些空表达式是不会显示的。第三个参数可以改变默认的行为。
*/
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
//boost::char_separator<char> sep(" ");
boost::char_separator<char> sep(" ", "+");
tokenizer tok1(s12, sep);
for (tokenizer::iterator it = tok1.begin(); it != tok1.end(); ++it)
std::cout << *it << std::endl;
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
boost::char_separator<char> sepwe(" ", "+", boost::keep_empty_tokens);
//第三个参数决定了是否显示空的部分表达式。 如果连续找到两个分隔符(空格和标点符号),他们之间的部分表达式将为空。
//在默认情况下,这些空表达式是不会显示的。第三个参数可以改变默认的行为。
tokenizer tok23(s12, sepwe);
for (tokenizer::iterator it = tok23.begin(); it != tok23.end(); ++it)
std::cout << *it << std::endl;
//***********另外两个类以识别部分表达式。
/*
boost::escaped_list_separator 类用于读取由逗号分隔的多个值,这个格式的文件通常称为 CSV
它甚至还可以处理双引号以及转义序列。所以本例的输出为 Boost 和 C++ libraries 。
*/
typedef boost::tokenizer<boost::escaped_list_separator<char> > tokenizerer;
std::string s65 = "Boost,\"C++ libraries\"";
tokenizerer tokdsd(s65);
for (tokenizerer::iterator it = tokdsd.begin(); it != tokdsd.end(); ++it)
std::cout << *it << std::endl;
//boost::offset_separator 类,必须用实例说明。
//这个类的对象必须作为第二个参数传递给 boost::tokenizer 类的构造函数。
/*
boost::offset_separator 指定了部分表达式应当在字符串中的哪个位置结束。
以上程序制定第一个部分表达式在 5 个字符后结束,第二个字符串在另 5 个字符后结束,
第三个也就是最后一个字符串应当在之后的 9 个字符后结束。 输出的结果为 Boost 、 C++ 和 libraries 。
*/
typedef boost::tokenizer<boost::offset_separator> tokenizeroffset;
//std::string s = "Boost C++ libraries";
int offsets[] = { 5, 9, 9 };
//参数为 begin 与end
boost::offset_separator sep1(offsets, offsets + 3);
tokenizeroffset tokss(s12, sep1);
for (tokenizeroffset::iterator it = tokss.begin(); it != tokss.end(); ++it)
std::cout << *it << std::endl;
//*************格式化输出库 Boost.Format
//Boost.Format 类使用置于两个百分号之间的数字作为占位符,占位符稍后通过 % 操作符与实际数据连接。
//以 16.9.2008的格式输出。
std::cout << boost::format("%1%.%2%.%3%") % 16 % 9 % 2008 << std::endl;
//如果要月份出现在日期之前,即美式表示,只需交换占位符即可。结果变成 9/16/2008 。
std::cout << boost::format("%2%/%1%/%3%") % 16 % 9 % 2008 << std::endl;
//操作器 std::showpos() 通过 boost::io::group() 与数字 99 连接,所以只要显示 99 , 在它前面就会自动加上加号。
std::cout << boost::format("%1% %2% %1%") % boost::io::group(std::scientific, 9999999999) % 100 << std::endl;
//如果需要加号仅在 99 第一次输出时显示, 则需要改造格式化占位符。
/*
需要将数据的引用符号由 1$ 变为 1% ,还需要在其两侧各添加一个附加的管道符号,即将占位符 %1% 替换为 %|1$+|。
结果为 +99 100 99
*/
std::cout << boost::format("%|1$+| %2% %1%") % 99 % 100 << std::endl;
/*
以下例子在执行时会出现错误,因为它给第二个和第三个占位符设置了引用但是却忽略了第一个。
*/
try
{
std::cout << boost::format("%|+| %2% %1%") % 99 % 100 << std::endl;
}
catch (boost::io::format_error& ex)
{
std::cout << ex.what() << std::endl;
}
//以下例子演示了不引用数据的方法。
//第二、第三个占位符的管道符号可以被安全地省略,因为在这种情况下,他们并不指定格式。
std::cout << boost::format("%|+| %|| %||") % 99 % 100 % 99 << std::endl;
//格式化字符串中字母 'd' 的使用并不表示输出数字,
//而是表示 boost::format 类所使用的内部流对象上的 std::dec() 操作器,
/*
它可以使用某些对 std::printf() 函数无意义的格式字符串,如果使用 std::printf() 会导致程序在运行时崩溃。
*/
std::cout << boost::format("%+d %d %d") % 99 % 100 % 99 << std::endl;
/*
在 std::printf() 函数中,字母 's' 只用于表示类型为 const char* 的字符串,然而以下程序却能正常运行。
在 Boost.Format 库中,这并不代表强制为字符串,它会结合适当的操作器,调整内部流的操作模式。
所以即使在这种情况下, 在内部流中加入数字也是没问题的。
*/
std::cout << boost::format("%+s %s %s") % 99 % 100 % 99 << std::endl;
system("pause");
return 0;
}