繁体   English   中英

从 C++ 中的字符串中提取标记

[英]Extracting tokens from string in C++

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

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

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

我怎样才能防止这种行为? 我认为这可以用正则表达式来完成,

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"

Output:

"!","aaa ","+","!"," a"

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

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

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


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

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

演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM