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

如何在不使用正则的前提下提取表达式负数存入数组

解决方案

原有直接按四则运算符拆分的逻辑,会把负数前的负号和作为运算符的减号混淆,导致负号被丢弃,无法正常识别负数。我们可以通过区分负号和减法运算符的逻辑实现无正则的数字提取,判断规则非常简单:只有两种场景下-是负号:

  • 它是整个表达式的第一个非空白字符
  • 它的前一个非空白字符是/、*、+、-四个运算符之一

其余场景下的-均为减法运算符,按拆分标记处理即可,完整实现代码如下:

private static readonly char[] validOperators = { '/', '*', '+', '-' };

public static List<double> GetNumbersFromExpression(string inputData)
{
    List<double> numbers = new List<double>();
    // 先清除所有空白字符,避免空格干扰判断逻辑
    string cleanedInput = new string(inputData.Where(c => !char.IsWhiteSpace(c)).ToArray());
    string currentNumber = string.Empty;

    for (int i = 0; i < cleanedInput.Length; i++)
    {
        char c = cleanedInput[i];
        // 判断当前字符为负号,而非减法运算符
        if (c == '-' && (i == 0 || validOperators.Contains(cleanedInput[i - 1])))
        {
            currentNumber += c;
        }
        // 数字或小数点归入当前数字字符串
        else if (char.IsDigit(c) || c == '.')
        {
            currentNumber += c;
        }
        // 遇到运算符则结束当前数字的读取
        else if (validOperators.Contains(c))
        {
            if (!string.IsNullOrEmpty(currentNumber))
            {
                numbers.Add(double.Parse(currentNumber));
                currentNumber = string.Empty;
            }
        }
        // 可选:非法字符校验,不需要可以删除该分支
        else
        {
            throw new ArgumentException($"表达式包含非法字符:{c}");
        }
    }

    // 读取表达式末尾的最后一个数字
    if (!string.IsNullOrEmpty(currentNumber))
    {
        numbers.Add(double.Parse(currentNumber));
    }

    return numbers;
}

用你提供的示例inputData = "-80 * 5-5"调用该方法,最终得到的数字列表为[-80, 5, 5],符合预期。该方案还有以下适配性:

  • 支持识别表达式中间的负数,例如"5*-3+2"会正确返回[5, -3, 2]
  • 支持带小数点的浮点数识别,不需要小数可以删除小数点判断逻辑
  • 纯字符串遍历实现,无额外依赖,性能和可维护性都高于正则方案

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 13:24:02