标记表达式字符串
Tokenizing a string of expression
我有一个字符串,格式如下:
(1 + 2 - 3) / 5
我想提取数字/运算符的位置,并将它们放入单独的容器中。最好的方法是什么?谢谢
更新:
字符串之间不一定有"ws"。例如,
(1+2 - 3)/5
应正确处理。
如果您不总是使用分隔符,可以使用flex
或flex++
为您构建扫描仪。你会给它正则表达式,它会处理剩下的。
如果您真的想评估该表达式,那么标记化是不够的。你可能想要的是调车场算法。这会生成一个很好的运算符和值堆栈,然后您可以对这些运算符和值进行求值以获得表达式的答案。
这个算法是我的Leaf解析器的基础。我使用boost::regex
提取单个令牌,并跳过该空间。处理一元"-"可能是最棘手的部分。
如果您真的只想将数字和运算符提取到容器中,那么只需使用两个正则表达式。一个匹配所有数字,一个匹配全部运算符。看看boost regex令牌迭代器。
如果保证数字和运算符之间有空格,那么使用例如std::istringstream
和普通输入运算符>>
将很好,因为输入运算符在空格上分离。
否则,你必须一次读取一个字符,并检查它是什么类。比如,如果它是一个数字,那么你就有一个数字;如果它是空格,那么忽略它;或者如果它是其他字符,那么它可能是一个运算符。
由于运算符之间似乎没有空格(就像您的示例中那样),因此您必须采用第二种方式。您可能想要搜索"lexer"或"词法分析"。
一些简单的伪代码让你开始:
struct token
{
enum
{
NUMBER,
OPERATOR
} type;
int num; // If `type` is `NUMBER`
std::string op; // If `type` is `OPERATOR`
};
token get_token()
{
char c = get_single_char();
// Skip whitespace
while (std::isspace(c))
c = get_single_char();
if (std::isdigit(c))
{
// A number
int n = 0;
while (std::isdigit(c))
{
n = n * 10 + (c - '0');
c = get_single_char();
}
// Here we have gotten one character to many, put it back
put_back_char(c);
token t = { NUMBER, n, "" };
return t;
}
// We have an operator
token t;
t.type = token::OPERATOR;
t.op += c;
return t;
}
对于您的示例,我将使用strtok()
此处的示例:http://www.cplusplus.com/reference/cstring/strtok/
相关文章:
- 使用正则表达式regex_search在字符串中查找字符串
- C++ 编译错误:意外的类型名称"字符串":预期的表达式
- 如何在C++中使用正则表达式"|"后选择字符串?
- 生成 constexpr 字符串表,不能产生常量表达式
- 如何在 c++11 中使用正则表达式找到确切的子字符串?
- 如何编写将验证以下字符串的正则表达式?
- C++带有捕获组的正则表达式字符串文本
- 如何使用正则表达式从字符串中提取值
- 使用正则表达式c++从单词和分隔符之间的字符串中提取所有子字符串
- 使用宏将字符串解析为表达式C++
- 如何在没有外部库的情况下使用C++03约束执行基于正则表达式的字符串操作
- 需要忽略日期/序列号,但匹配字符串其余部分的正则表达式
- 如何将正则表达式向量与一个字符串匹配?
- 计算表达式字符串由 std::map 中的键组成
- 正则表达式匹配字符串之间的数字
- 如何根据某个索引将字符串与正则表达式匹配?
- 根据某些规则检查字符串表达式的有效性
- C++字符串表达式求解器遇到访问冲突
- 如何使用RegExp验证字符串表达式
- Boost Spirit Qi解析器不消耗整个字符串表达式