【问题标题】:Tokenizing mathematical expression with words用单词标记数学表达式
【发布时间】:2018-03-04 11:51:31
【问题描述】:

我们有 C++ 中的 regex 库。通过使用它,我想 parse tokenize 下面的数学表达式。

(bar+3)*foo/3+-1

作为

(
bar
+
3
)
*
foo
/
3
+
-1

为此,我尝试了那个,但它没有提供与预期相反的输出,而不是标记

std::string s ("(bar+3)*foo/3+-1");
std::smatch m;
std::regex e ("^[-+(]*[[:digit:]]+[)]*([-+*/][-+(]*[[:digit:]]+[)]*)*$");

怎么做?

编辑:抱歉写错了。

【问题讨论】:

  • 定义“不起作用” - 会发生什么?遇到什么错误,调试时看到什么等?
  • 固定@UnholySheep
  • 上面的正则表达式显然是错误的,因为它不匹配任何字母字符,但您的目标字符串包含字母字符。
  • 正则表达式无法解析递归语言。数学表达式是递归语言。所以我认为你可能选择了错误的工具来完成这项工作。
  • @snr 困难的部分是您希望- 成为整数的一部分,但您可能也希望它成为运算符-1+-x,第一个减号是整数,但第二个是一元减号。如果您准备放弃该要求(并始终将- 视为操作员),那将会更容易。

标签: c++ regex c++11


【解决方案1】:

这段代码标记了一个数学表达式

int main()
{
    string s = "(bar+3)*foo/3+-1";
    regex re("[[:digit:]]+|[[:alpha:]][[:alnum:]]*|[-+*/()]");
    auto tokens_begin = 
        std::sregex_iterator(s.begin(), s.end(), re);
    auto tokens_end = std::sregex_iterator();
    while (tokens_begin != tokens_end)
    {
        cout << tokens_begin->str() << endl;
        ++tokens_begin;
    }
}

输出

(
bar
+
3
)
*
foo
/
3
+
-
1

在此代码中,- 始终被视为运算符,因此 -1 被视为一元减号后跟无符号数。如果不进行一些真正的解析,可能不可能做得比这更好。

【讨论】:

  • 非常感谢您的帮助。我的最后一点是,通过添加-?[0-9]+([.][0-9]+)?,数字是 3.412 的两倍呢??
  • 你会遇到用'-?'开始你的正则表达式的问题正如我在上面的 cmets 中解释的一元减号。考虑对 x-1.0 进行标记,在这种情况下,您可能不希望减号成为您的数字的一部分,但使用该正则表达式它将是。最简单的事情是将所有数字视为无符号,
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多