You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用正则提取算术表达式元素入栈时出现空字符串的问题求助

解决C++正则拆分表达式时出现空字符串的问题及后缀表达式实现思路

问题原因分析

你的代码出现空字符串主要有两个核心原因:

  1. 正则表达式的分支匹配逻辑:你用了[0-9]*(匹配0个或多个数字),这个分支允许匹配空字符串。当正则引擎遇到非数字字符(比如*、()时,会优先匹配这个分支的空结果,从而产生空token。
  2. std::smatch的遍历方式:你的正则包含一个捕获组(...),所以smatch中会包含整个匹配结果(索引0)和捕获组内容(索引1)。遍历smatch时会输出这两个元素,比如匹配运算符时,捕获组可能是空,就会输出空串;同时你只调用了一次regex_search,无法获取所有token。

另外,你的正则还遗漏了幂运算符^,也没有处理原字符串中的空格,这些都会影响后续的token提取。

修正方案

1. 修正正则表达式

把[0-9]*改为[0-9]+(匹配1个或多个数字,避免空匹配),加入幂运算符^,同时可以匹配空格以便后续过滤:

std::regex tokenRegex(R"(\d+|[+*\-/%^()]|\s+)");

这里用了原始字符串字面量R"(...)",避免了转义字符的繁琐。

2. 正确遍历所有匹配结果

使用循环调用regex_search,每次更新搜索的起始位置,确保提取出所有token。

3. 过滤无效token并区分栈存储

提取token后,先过滤空格,然后判断是操作数还是运算符/括号,分别存入对应的栈。

完整修正代码

#include <iostream>
#include <string>
#include <regex>
#include <stack>
#include <cctype>
#include <algorithm>

void Stack::findIT() {
    std::string expr = "56*((6+2)/(8-7)* 2^3)";
    // 修正后的正则:匹配数字、运算符、括号、空格
    std::regex tokenRegex(R"(\d+|[+*\-/%^()]|\s+)");
    std::smatch matchResult;
    auto searchStart = expr.cbegin();

    std::stack<int> operandStack;
    std::stack<char> operatorStack;

    while (std::regex_search(searchStart, expr.cend(), matchResult, tokenRegex)) {
        std::string token = matchResult[0];
        
        // 过滤空格类型的token
        if (std::all_of(token.begin(), token.end(), ::isspace)) {
            searchStart = matchResult.suffix().first;
            continue;
        }

        // 判断是操作数还是运算符/括号,分别入栈
        if (std::isdigit(token[0])) {
            // 转换为整数存入操作数栈(如果需要支持浮点数可以用stod)
            operandStack.push(std::stoi(token));
            std::cout << "操作数入栈:" << token << "\n";
        } else {
            // 运算符或括号存入运算符栈
            operatorStack.push(token[0]);
            std::cout << "运算符/括号入栈:" << token << "\n";
        }

        // 更新下一次搜索的起始位置
        searchStart = matchResult.suffix().first;
    }

    // 后续可以在这里实现后缀表达式的转换逻辑(比如Shunting-yard算法)
}

额外说明

如果需要支持浮点数(比如3.14),可以把正则中的\d+改为\d+(\.\d+)?,并将std::stoi改为std::stod。另外,实现后缀表达式转换建议参考调度场算法(Shunting-yard Algorithm),它能很好地处理运算符优先级和括号。

内容的提问来源于stack exchange,提问作者Benjamin Sx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:43:25