在C ++中从字符串中提取令牌

时间:2020-08-08 19:50:32

标签: c++ regex string

编辑:我正在寻找一个不使用正则表达式的解决方案,因为它似乎有错误并且不可信

我有以下函数,只要找到以下符号之一,它就会提取字符串的标记:+,-,^,*,!

bool extract_tokens(string expression, std::vector<string> &tokens) {    
    static const std::regex reg(R"(\+|\^|-|\*|!|\(|\)|([\w|\s]+))");
    std::copy(std::sregex_token_iterator(right_token.begin(), right_token.end(), reg, 0),
              std::sregex_token_iterator(),
              std::back_inserter(tokens));
    return true;
}

直到今天我一直工作得很好,我发现了一个极端的情况, 以下输入:!aaa +! a应该返回!,aaa ,+,!, a,但它返回!,aaa ,+,"",!, a,请注意+和!之间多余的空字符串。

我如何防止这种行为?我认为这可以通过正则表达式来完成,

2 个答案:

答案 0 :(得分:1)

为了挽救基于正则表达式的解决方案,我想到了这一点:

[-+^*!()]|\s*[^-+^*!()\s][^-+^*!()]*

Demo。该报告报告定界符以及定界符之间的任何内容,包括前导和尾随空白,但会丢弃仅由空白组成的令牌。


一个类似的表达式也去除了开头和结尾的空格:

[-+^*!()]|[^-+^*!()\s]+(\s+[^-+^*!()\s]+)*)

Demo

答案 1 :(得分:0)

https://stackoverflow.com/a/9436872/4645334的启发,您可以使用以下方法解决问题:

bool extract_tokens(std::string expression, std::vector<std::string> &tokens) {
  std::string token;

  for (const auto& c: expression) {
    if (c == '/' || c == '-' || c == '*' || c == '+' || c == '!') {
      if (token.length() && !std::all_of(token.cbegin(), token.cend(), [](auto c) { return c == ' '; })) tokens.push_back(token);
      token.clear();
      tokens.emplace_back(1, c);
    } else {
      token += c;
    }
  }

  if (token.length() && !std::all_of(token.cbegin(), token.cend(), [](auto c) { return c == ' '; })) tokens.push_back(token);
     
  return true;
}

输入:

"!aaa + ! a"

输出:

"!","aaa ","+","!"," a"
相关问题