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

C#高性能自定义字符串首尾修剪需求及代码问题求助

自定义字符串首尾修剪解决方案

需求说明

需要处理任意长度的字符串,完成以下操作:

  • 从字符串首尾修剪所有符合条件的内容,直到遇到不符合条件的字符为止:
    • 单个字符:空格、#、制表符(\t)
    • 连续片段://、/*、*/(必须是连续的完整片段,中间夹杂其他字符则停止修剪)
  • 统计首尾各自被修剪的字符数量
  • 要求高性能,优先使用循环实现,避免正则表达式

现有问题

当前尝试的C#代码无法正确处理连续的目标片段,例如:

  • 输入 "///g, hhh/ , test" 被错误修剪为 "g, hhh/ , test"(正确结果应为 "/g, hhh/ , test")
  • 输入 "/*g, hhh/ , test" 被错误修剪为 "*g, hhh/ , test"(正确结果应为 "g, hhh/ , test")

尝试的错误代码

private const char specialSymbol_1 = '/';
private const char specialSymbol_2 = '*';
private const char specialSymbol_3 = '#';

private void ObserveTrim(ref string target, ref int start, ref int end) {
    int s = 0; int e = 0;
    
    for (int i = 0; i < target.Length; ++i) {
        char c = target[i];
        
        bool flag = false;
        if (target.Length > 1) {
            if (i == 0) {
                flag = c == specialSymbol_1 && target[i + 1] == specialSymbol_1 ||
                    c == specialSymbol_1 && target[i + 1] == specialSymbol_2 ||
                    c == specialSymbol_2 && target[i + 1] == specialSymbol_1;
            }
            else if (i == target.Length - 1) {
                flag = c == specialSymbol_1 && target[i - 1] == specialSymbol_1 ||
                    c == specialSymbol_1 && target[i - 1] == specialSymbol_2 ||
                    c == specialSymbol_2 && target[i - 1] == specialSymbol_1;
            }
            else {
                flag = c == specialSymbol_1 && target[i + 1] == specialSymbol_1 ||
                    c == specialSymbol_1 && target[i - 1] == specialSymbol_1 ||
                    c == specialSymbol_1 && target[i + 1] == specialSymbol_2 ||
                    c == specialSymbol_1 && target[i - 1] == specialSymbol_2;
            }
        }
        
        if (flag) continue;
        
        if (!char.IsWhiteSpace(c) && c != specialSymbol_3) {
            s = i;
            break;
        }
    }
    
    for (int i = target.Length - 1; i >= 0; --i) {
        char c = target[i];
        
        bool flag = false;
        if (target.Length > 1) {
            if (i == 0) {
                flag = c == specialSymbol_1 && target[i + 1] == specialSymbol_1 ||
                    c == specialSymbol_1 && target[i + 1] == specialSymbol_2 ||
                    c == specialSymbol_2 && target[i + 1] == specialSymbol_1;
            }
            else if (i == target.Length - 1) {
                flag = c == specialSymbol_1 && target[i - 1] == specialSymbol_1 ||
                    c == specialSymbol_1 && target[i - 1] == specialSymbol_2 ||
                    c == specialSymbol_2 && target[i - 1] == specialSymbol_1;
            }
            else {
                flag = c == specialSymbol_1 && target[i + 1] == specialSymbol_1 ||
                    c == specialSymbol_1 && target[i - 1] == specialSymbol_1 ||
                    c == specialSymbol_1 && target[i + 1] == specialSymbol_2 ||
                    c == specialSymbol_1 && target[i - 1] == specialSymbol_2;
            }
        }
        
        if (flag) continue;
        
        if (!char.IsWhiteSpace(c) && c != specialSymbol_3) {
            e = target.Length - 1 - i;
            break;
        }
    }
    
    start += s;
    end -= e;
    target = target.Substring(s, target.Length - s - e);
}

正确实现方案

核心思路:

  1. 头部遍历:逐个检查字符,优先匹配完整片段,再匹配单个修剪字符,匹配成功则跳过对应长度,直到遇到非修剪内容
  2. 尾部遍历:从末尾反向检查,逻辑与头部一致,匹配成功则向前跳过对应长度
  3. 最终根据遍历结果截取子串,同时统计首尾修剪的字符数
private static readonly char[] _singleTrimChars = { ' ', '\t', '#' };
private static readonly string[] _prefixTrimSegments = { "//", "/*" };
private static readonly string[] _suffixTrimSegments = { "//", "*/" };

public static void CustomTrim(ref string input, out int trimmedFromStart, out int trimmedFromEnd)
{
    trimmedFromStart = 0;
    trimmedFromEnd = 0;

    if (string.IsNullOrEmpty(input))
        return;

    // 处理头部修剪
    int startIndex = 0;
    int length = input.Length;
    while (startIndex < length)
    {
        bool trimmed = false;

        // 检查单个可修剪字符
        if (Array.IndexOf(_singleTrimChars, input[startIndex]) != -1)
        {
            startIndex++;
            trimmedFromStart++;
            trimmed = true;
        }
        else
        {
            // 检查前缀片段
            foreach (var seg in _prefixTrimSegments)
            {
                if (startIndex + seg.Length <= length && input.Substring(startIndex, seg.Length) == seg)
                {
                    startIndex += seg.Length;
                    trimmedFromStart += seg.Length;
                    trimmed = true;
                    break;
                }
            }
        }

        if (!trimmed)
            break;
    }

    // 处理尾部修剪
    int endIndex = length - 1;
    while (endIndex >= startIndex)
    {
        bool trimmed = false;

        // 检查单个可修剪字符
        if (Array.IndexOf(_singleTrimChars, input[endIndex]) != -1)
        {
            endIndex--;
            trimmedFromEnd++;
            trimmed = true;
        }
        else
        {
            // 检查后缀片段
            foreach (var seg in _suffixTrimSegments)
            {
                int segLen = seg.Length;
                if (endIndex - segLen + 1 >= startIndex && input.Substring(endIndex - segLen + 1, segLen) == seg)
                {
                    endIndex -= segLen;
                    trimmedFromEnd += segLen;
                    trimmed = true;
                    break;
                }
            }
        }

        if (!trimmed)
            break;
    }

    // 更新结果字符串
    if (startIndex <= endIndex)
        input = input.Substring(startIndex, endIndex - startIndex + 1);
    else
        input = string.Empty;
}

测试验证

针对问题中的测试用例:

  1. 输入 "///g, hhh/ , test":
    • 头部匹配//(前2个字符),修剪2个字符;剩余的/不属于修剪范围,停止头部修剪
    • 最终结果:"/g, hhh/ , test",头部修剪2个字符,尾部修剪0个
  2. 输入 "/*g, hhh/ , test":
    • 头部匹配/*(前2个字符),修剪2个字符;后续的g不符合修剪条件,停止头部修剪
    • 最终结果:"g, hhh/ , test",头部修剪2个字符,尾部修剪0个

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 11:39:59