Boost.Tokenizer用于引号和圆括号
Boost.Tokenizer for quotation marks and parentheses
我想使用Boost.Tokenize
将字符串拆分为令牌。要求引号或圆括号中的文本是单个完整标记。更具体地说,我需要像一样拆分一条线
"one (two),three" four (five "six".seven ) eight(nine, ten)
转换为等代币
one (two),three
four
(five "six".seven )
eight
(nine, ten)
或者
one (two),three
four
(
five "six".seven
)
eight
(
nine, ten
)
我知道用引号标记文本的方法,但我不知道如何同时用父子关系标记文本。可能需要实现TokenizerFunction
如何像我描述的那样拆分字符串?
TokenizerFunction是一个有两个方法的函子,这两个方法都不太容易实现。第一个是reset
,它意味着重置函子可能具有的任何状态,另一个是operator()
,它有三个参数。前两个是迭代器,第三个是生成的令牌。
下面的算法很简单。首先,我们跳过任何空格。我们期望第一个非空间字符是三种类型中的一种。如果是引号或左括号,那么我们进行搜索,直到找到相应的结束分隔符,并返回我们找到的内容作为标记,注意引号应该被去掉,但括号显然会保留下来。如果第一个字符是其他字符,那么我们搜索下一个分隔符并返回它。
template <
typename Iter = std::string::const_iterator,
typename Type = std::string
>
struct QuoteParenTokenizer
{
void reset() { }
bool operator()(Iter& next, Iter end, Type& tok) const
{
while (next != end && *next == ' ')
++next;
if (next == end)
return false; // nothing left to read
switch (*next) {
case '"': {
++next; // skip token start
Item const quote = std::find(next, end, '"');
if (quote == end)
return false; // unterminated token
tok.assign(next, quote);
next = quote;
++next;
break;
}
case '(': {
Iter paren = std::find(next, end, ')');
if (paren == end)
return false; // unterminated token
++paren; // include the parenthesis
tok.assign(next, paren);
next = paren;
break;
}
default: {
Iter const first = next;
while (next != end && *next != ' ' && *next != '"' && *next != '(')
++next;
tok.assign(first, next);
}
}
return true;
}
};
您可以将其实例化为tokenizer<QuoteParenTokenizer<> >
。如果您有不同的迭代器类型或不同的令牌类型,则需要在tokenizer
和QuoteParenTokenizer
的模板参数中指示它们。
如果您需要处理转义的分隔符字符,您可能会变得更喜欢。如果你需要插入括号的表达式来嵌套,事情会更棘手。
请注意,截至目前,上述代码尚未经过测试。
相关文章:
- C++decltype和圆括号-为什么
- 为什么标准首选圆括号初始化为"make_<something>"?
- 函数调用中的多个圆括号
- Boost Tokenizer无法解析具有带有双引号的字段的CSV文件
- 方括号和圆括号操作器,如何选择重载
- 逗号运算符与圆括号表达式的用法示例
- 与圆括号和运算符 () 一起使用的结构名称
- 检测圆括号,包括打开和关闭
- 从 Boost::Tokenizer 中删除重复项
- C++:指针,然后是圆括号 - 这是什么意思
- 函数调用周围的圆括号
- 放置额外的圆括号-代码无法编译
- 查找最外圆括号内的字符串
- 使用堆栈来确定表达式是否具有平衡圆括号
- Boost.Tokenizer如何不从令牌中删除分隔符
- 重载圆括号()是否影响构造函数调用
- 成员初始值设定项列表表示法:大括号与圆括号
- 圆括号明显的语法错误C++但编译器没有抱怨
- 重载赋值和C++中的圆括号运算符
- Boost.Tokenizer用于引号和圆括号