符号化表达
的字符串我有以下形式的字符串:符号化表达
(1 + 2 - 3)/5
如果我想提取号码/运营商和把它们放在不同的容器中。什么是最好的方式来做到这一点?谢谢!
更新:
字符串不一定有他们之间的 “WS”。例如,
(1+2 - 3)/5
应该被正确处理。
如果你真的想评估这个表达式,那么标记就不够了。你可能想要的是shunting yard algorithm。这产生了一堆很好的运算符和值,然后您可以评估它们以获取表达式的答案。
这个算法是我的解析器的基础Leaf。我使用boost::regex
提取单个令牌并跳过该空间。处理一元' - '可能是最棘手的部分。
如果你真的只想提取数字和运算符到容器中,那么只需使用两个正则表达式。一个匹配所有数字,一个匹配所有运营商。看看boost正则表达式迭代器。
谢谢你的回答!任何提示实施一元减号? – JASON
它是一个高优先级的右联合算子。在algortihm中有条件提到左优先,因此一元减因此是正确的。高优先级,因为它适用于大多数其他运营商之前。 –
如果在数字和运算符之间保证有空格,则使用例如std::istringstream
和正常输入运算符>>
将正常工作,因为输入运算符在空间上分离。
否则,您必须一次读取一个字符,并检查它是什么类。就像它是一个数字那么你有一个数字,如果它是一个空格然后忽略它,或者如果它是别的东西,那么它可能是一个操作符。
由于看起来运营商之间可能没有空格(就像你的例子),那么你必须采取第二种方式。您可能想要搜索“词法分析器”或“词法分析”。
一些简单的伪代码,让您开始:
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;
}
strchr(“+ - ”)...如果需要高级解析形式,请查看ANTLR。 – bvj
提升精神这样做。这里有一篇文章[解析你描述的内容](http://www.codeproject.com/Articles/8516/An-Introduction-to-the-Boost-Spirit-Parser-framewo)。 –