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

如何将字符串拆分为词法单元(lexeme)?C#现有实现问题求解

问题根因分析

  1. 为什么会跳过Sin参数内内容/运行报错
    你当前的匹配逻辑存在2个致命错误:
  • 操作符前缀匹配后,没有校验最终拼接的currentOp是否真的存在于操作符列表中:比如匹配S1时,前缀S匹配到Sin的前缀,但拼接上1后无匹配前缀,此时得到的currentOp是S,而你的操作符列表里没有S,执行Single查询会直接抛出未找到序列的异常,如果你上层吞了异常就会出现后续内容被跳过的情况。
  • 索引处理错误:当你匹配完数字后索引i已经指向非数字字符,操作符匹配结束后又执行了i--,如果操作符匹配长度为1的话,下一轮循环i++会导致重复读取同一个字符,逻辑混乱。
  1. 为什么检测不到非法词法单元
    你没有对匹配失败的情况做兜底判断:当匹配完数字后,当前字符既不能拼接为合法操作符,也不属于数字开头,就属于非法词法单元,你当前代码没有对这种场景做捕获。

修复&优化后的实现

前置优化点

  • 提前把操作符按长度倒序排序,优先匹配长操作符(避免把Sin拆成S/i/n单个字符)
  • 操作符查询用哈希集合做O(1)校验,避免每次遍历整个列表
  • 增加非法字符的判断分支
// 提前准备排序后的操作符列表,不用每次循环遍历,优先匹配长词提升准确率
var sortedOps = operations.Select(x => x.Name).OrderByDescending(name => name.Length).ToList();

const string input = "(2+2)*3S1(2)+Sin(1+2/S1(2))";
var lexemes = new List<string>();
int i = 0;
while (i < input.Length)
{
    // 跳过空格(如果不需要支持空格输入可删除该段)
    if (char.IsWhiteSpace(input[i]))
    {
        i++;
        continue;
    }

    // 1. 先匹配数字
    if (char.IsDigit(input[i]) || input[i] == '.')
    {
        var numBuilder = new StringBuilder();
        while (i < input.Length && (char.IsDigit(input[i]) || input[i] == '.'))
        {
            numBuilder.Append(input[i]);
            i++;
        }
        lexemes.Add(numBuilder.ToString());
        continue;
    }

    // 2. 匹配操作符/函数名
    bool matchedOp = false;
    foreach (var op in sortedOps)
    {
        if (i + op.Length <= input.Length && input.Substring(i, op.Length) == op)
        {
            lexemes.Add(op);
            i += op.Length;
            matchedOp = true;
            break;
        }
    }

    if (matchedOp)
    {
        continue;
    }

    // 3. 既不是数字也不是合法操作符,抛出非法词法异常
    throw new InvalidOperationException($"非法词法单元:位置 {i} 的 {input[i]} 开头的内容不属于合法操作符或数字");
}

// 合法输入下可拿到最终词法数组
Console.WriteLine(string.Join(", ", lexemes));

运行效果

针对你给出的输入字符串,代码会在匹配到3后的S时抛出异常,提示S开头的内容不是合法词法单元,符合你的需求。如果把输入里的S1都替换为合法操作符,会正常输出拆分后的词法数组。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 15:00:02