符号化表达

问题描述:

的字符串我有以下形式的字符串:符号化表达

(1 + 2 - 3)/5 

如果我想提取号码/运营商和把它们放在不同的容器中。什么是最好的方式来做到这一点?谢谢!

更新:

字符串不一定有他们之间的 “WS”。例如,

(1+2 - 3)/5 

应该被正确处理。

+0

strchr(“+ - ”)...如果需要高级解析形式,请查看ANTLR。 – bvj

+0

提升精神这样做。这里有一篇文章[解析你描述的内容](http://www.codeproject.com/Articles/8516/An-Introduction-to-the-Boost-Spirit-Parser-framewo)。 –

如果你真的想评估这个表达式,那么标记就不够了。你可能想要的是shunting yard algorithm。这产生了一堆很好的运算符和值,然后您可以评估它们以获取表达式的答案。

这个算法是我的解析器的基础Leaf。我使用boost::regex提取单个令牌并跳过该空间。处理一元' - '可能是最棘手的部分。

如果你真的只想提取数字和运算符到容器中,那么只需使用两个正则表达式。一个匹配所有数字,一个匹配所有运营商。看看boost正则表达式迭代器。

+0

谢谢你的回答!任何提示实施一元减号? – JASON

+0

它是一个高优先级的右联合算子。在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; 
} 

对于你的榜样,我会用的strtok()

这里举例:http://www.cplusplus.com/reference/cstring/strtok/

如果你不” t总是有分隔符,您可以使用flexflex++为您构建扫描仪。你会给它正则表达式,而其余部分将会处理。

+0

谢谢!我也会试试flex – JASON