它的核心包括,template < class TokenizerFunc = char_delimiters_separator<char>, class Iterator = std::string::const_iterator, class Type = std::string > class tokenizer
tokenizer(Iterator first, Iterator last,const TokenizerFunc& f = TokenizerFunc()) template<class Container> tokenizer(const Container& c,const TokenizerFunc& f = TokenizerFunc())
其中参数的意义如下:
参数 | 描述 |
c | 一个包含被分解的序列的容器。注:c.begin() 和 c.end() 必须可以转换为模板参数 Iterator. |
f | 一个符合 TokenizerFunction 的函数对象,用于对序列进行分解。 |
first | 迭代器,表示被分解序列的开始位置。 |
last | 迭代器,表示被分解序列的末尾位置。 |
#include<iostream>
#include<boost/tokenizer.hpp>
#include<string>
int main(){
using namespace std;
using namespace boost;
string s = "This is, a test";
tokenizer<> tok(s);
//tokenizer通过迭代器来访问分割后的字符序列,字符分割是在遍历过程中进行的,而不是构造函数
for(tokenizer<>::iterator beg=tok.begin(); beg!=tok.end();++beg){
cout << *beg << "\n";
}
}
char_separator
类基于字符分隔符来分解一个字符序列,就象 strtok()
所做的那样(但没有不可重入以及输入序列析构的问题)。
char_separator
类与 token_iterator
或 tokenizer
一起使用以执行单词分解。
strtok()
函数在单词输出序列中不包含用于匹配的字符分隔符。但是,在输出序列中显示这些分隔符有时候是有用的,所以 char_separator
将这个功能作为一个选项提供。我们将在输出单词中包含分隔符称为 保留分隔符 ,而将在输出单词中不包含分隔符称为 被弃分隔符。
当在输入序列中出现两个连续的分隔符时,有一个问题就是是否要输出一个 空白单词 或是直接跳过。strtok()
的行为是跳过。而 char_separator
类则提供了两个选项。
第一个例子示范如何将 char_separator
作为 strtok()
函数的替代物来使用。我们指定了三个字符分隔符,它们不出现在输出单词中。我们没有指定任何保留分隔符,而且缺省情况是忽略空白单词。
输出结果是:// char_sep_example_1.cpp #include <iostream> #include <boost/tokenizer.hpp> #include <string> int main() { std::string str = ";;Hello|world||-foo--bar;yow;baz|"; typedef boost::tokenizer<boost::char_separator<char> > tokenizer; boost::char_separator<char> sep("-;|"); tokenizer tokens(str, sep); for (tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter) std::cout << "<" << *tok_iter << "> "; std::cout << "\n"; return EXIT_SUCCESS; }
<Hello> <world> <foo> <bar> <yow> <baz>
下一个例子示范了用两个被弃分隔符 '-' 和 ';' 以及一个保留分隔符 '|' 来进行单词分解。我们还指定了当出现两个连续的分隔符时,要在输出中包含空白单词。
输出结果是:// char_sep_example_2.cpp #include <iostream> #include <boost/tokenizer.hpp> #include <string> int main() { std::string str = ";;Hello|world||-foo--bar;yow;baz|"; typedef boost::tokenizer<boost::char_separator<char> > tokenizer; boost::char_separator<char> sep("-;", "|", boost::keep_empty_tokens); tokenizer tokens(str, sep); for (tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter) std::cout << "<" << *tok_iter << "> "; std::cout << "\n"; return EXIT_SUCCESS; }
<> <> <Hello> <|> <world> <|> <> <|> <> <foo> <> <bar> <yow> <baz> <|> <>
最后一个例子示范了使用 char_separator
的缺省构造函数,按标点和空格来进行单词分解。
输出结果是:// char_sep_example_3.cpp #include <iostream> #include <boost/tokenizer.hpp> #include <string> int main() { std::string str = "This is, a test"; typedef boost::tokenizer<boost::char_separator<char> > Tok; boost::char_separator<char> sep; // 缺省构造 Tok tok(str, sep); for(Tok::iterator tok_iter = tok.begin(); tok_iter != tok.end(); ++tok_iter) std::cout << "<" << *tok_iter << "> "; std::cout << "\n"; return EXIT_SUCCESS; }
<This> <is> <,> <a> <test>
参数 | 描述 | 缺省值 |
---|---|---|
Char | 单词中的元素类型,通常为 char . |
|
Traits | 字符类型的 char_traits . | char_traits<char> |
escaped_list_separator
类是 TokenizerFunction 的一个实现。escaped_list_separator 对一个 csv (逗号分隔) 格式进行分解。以下是该模式的一些例子。它使用缺省的分隔符、引号和转义符。
Field 1,Field 2,Field 3
Field 1,"Field 2, with comma",Field 3
Field 1,Field 2 with \"embedded quote\",Field 3
Field 1, Field 2 with \n new line,Field 3
Field 1, Field 2 with embedded \\ ,Field 3
字段通常以逗号分隔。如果你想把逗号放入字段中,你就要用引号把它括起来。另外还支持以下三个转义序列
转义序列 | 结果 |
<escape><quote> | <quote> |
<escape>n | newline |
<escape><escape> | <escape> |
其中 <quote> 是指定为引号的任意字符,而 <escape> 则是指定为转义字符的任意字符。
// simple_example_2.cpp #include<iostream> #include<boost/tokenizer.hpp> #include<string> int main(){ using namespace std; using namespace boost; string s = "Field 1,\"putting quotes around fields, allows commas\",Field 3"; tokenizer<escaped_list_separator<char> > tok(s); for(tokenizer<escaped_list_separator<char> >::iterator beg=tok.begin(); beg!=tok.end();++beg){ cout << *beg << "\n"; } }
escaped_list_separator 有两个构造函数。分别如下:
explicit escaped_list_separator(Char e = '\\', Char c = ',',Char q = '\"')
参数 | 描述 |
e | 指定用作转义的字符。缺省使用 C 风格的 \ (反斜杠)。但是你可以传入不同的字符来覆盖它。你可能会这样做的一个例子是,如果你有很多字段是 Windows 风格的文件名时,路径中的每个 \ 都要转义。你可以使用其它字符作为转义字符。 |
c | 指定用作字段分隔的字符 |
q | 指定用作引号的字符 |
escaped_list_separator(string_type e, string_type c, string_type q):
参数 | 描述 |
e | 字符串 e 中的字符都被视为转义字符。如果给定的是空字符串,则没有转义字符。 |
c | 字符串 c 中的字符都被视为分隔符。如果给定的是空字符串,则没有分隔符。 |
q | 字符串 q 中的字符都被视为引号字符。如果给定的是空字符串,则没有引号字符。 |
使用这个类时,将它的某个对象传给 Tokenizer 包中需要 TokenizerFunction 的地方。
参数 | 描述 |
---|---|
Char | 单词中的元素类型,通常为 char . |
Traits | 字符类型的 traits 类,用于比较字符。缺省为 std::char_traits<Char> |
offset_separator
类是 TokenizerFunction 概念的一个实现,用于 tokenizer 类进行单词分解。offset_separator
按偏移量将一个字符序列分解为多个字符串。例如,如果你有一个字符串 "12252001" 和偏移量 (2,2,4),则它将该字符串分解为 12 25 2001. 例子如下:
// simple_example_3.cpp #include<iostream> #include<boost/tokenizer.hpp> #include<string> int main(){ using namespace std; using namespace boost; string s = "12252001"; int offsets[] = {2,2,4}; offset_separator f(offsets, offsets+3); tokenizer<offset_separator> tok(s,f); for(tokenizer<offset_separator>::iterator beg=tok.begin(); beg!=tok.end();++beg){ cout << *beg << "\n"; } }
offset_separator 有一个有用的构造函数(缺省构造函数只是为了让某些编译器高兴)。声明如下:
template<typename Iter>
offset_separator(Iter begin,Iter end,bool bwrapoffsets = true, bool breturnpartiallast = true)
参数 | 描述 |
begin, end | 指定整数偏移量序列 |
bwrapoffsets | 指明当所有偏移量用完后是否回绕到偏移量序列的开头继续。例如字符串 "1225200101012002" 用偏移量 (2,2,4) 分解,如果 bwrapoffsets 为 true, 则分解为 12 25 2001 01 01 2002. 如果 bwrapoffsets 为 false, 则分解为 12 25 2001,然后就由于偏移量用完而结束。 |
breturnpartiallast | 指明当被分解序列在生成当前偏移量所需的字符数之前结束,是否创建一个单词,或是忽略它。例如字符串 "122501" 用偏移量 (2,2,4) 分解,如果 breturnpartiallast 为 true,则分解为 12 25 01. 如果为 false, 则分解为 12 25,然后就由于序列中只剩下2个字符不足4个而结束。 |
使用这个类时,将它的某个对象传入到任何需要 TokenizerFunction 的地方。如果该对象是缺省构造的,则被分解序列中的每个字符将被作为一个单词返回(即缺省值为偏移量 1, 且 bwrapoffsets 为 true)。