【问题标题】:Extracting tokens from string in C++在 C++ 中从字符串中提取标记
【发布时间】:2020-11-28 20:15:36
【问题描述】:

编辑:我正在寻找一种不使用正则表达式的解决方案,因为它看起来有问题且不可信

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

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 请注意 + 和 ! 之间的额外空字符串。

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

【问题讨论】:

标签: c++ regex string


【解决方案1】:

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"

【讨论】:

  • std::string(c, 1) 不会编译。您的意思可能是tokens.push_back(c)。无论如何,这与原始问题存在相同的问题 - 它产生仅由空格组成的标记。 OP 希望将 ! + 拆分为两个令牌 !+,而不是三个令牌。
  • @IgorTandetnik c 是一个字符。 tokens.push_back(c) 不会编译:wandbox.org/permlink/cx8csmVomCMroaiy
  • 啊,对不起。我混淆了tokentokens。尽管如此,要构造一个字符的字符串,它应该是std::string(1, c)。你的论点是错误的。
【解决方案2】:

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

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

Demo。这会报告分隔符,以及分隔符之间的任何内容,包括前导空格和尾随空格,但会丢弃仅由空格组成的标记。


一个类似的表达式也去除了前导和尾随空格:

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

Demo

【讨论】:

    猜你喜欢
    • 2021-05-22
    • 2012-06-08
    • 2020-11-26
    • 1970-01-01
    • 2015-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多