编辑:我正在寻找一个不使用正则表达式的解决方案,因为它似乎有错误并且不可信
我有以下函数,只要找到以下符号之一,它就会提取字符串的标记:+,-,^,*,!
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
,请注意+和!之间多余的空字符串。
我如何防止这种行为?我认为这可以通过正则表达式来完成,
答案 0 :(得分:1)
为了挽救基于正则表达式的解决方案,我想到了这一点:
[-+^*!()]|\s*[^-+^*!()\s][^-+^*!()]*
Demo。该报告报告定界符以及定界符之间的任何内容,包括前导和尾随空白,但会丢弃仅由空白组成的令牌。
一个类似的表达式也去除了开头和结尾的空格:
[-+^*!()]|[^-+^*!()\s]+(\s+[^-+^*!()\s]+)*)
答案 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"