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

求提取字符串中{}内占位符的高效C#函数(兼容错误与嵌套)

问题

需要编写一个函数,接收包含{}标识占位符的字符串,提取所有占位符并生成列表。

示例

输入字符串:

"Good Morning {FIRSTNAME}, We are reaching out to inform you of your appointment with {INTERVIEWRE} on {APPTDATE} at {APPTTIME]. Please arrive by {ARRIVEBYTIME} and bring a copy of your resume."

预期输出列表:

["FIRSTNAME","INTERVIEWRE","APPTDATE","APPTTIME","ARRIVEBYTIME"]

附加要求

  • 占位符可能存在嵌套(比如{FIRSTNAME{LASTNAME}})
  • 需要兼容人工输入的错误(后续用于错误处理,校验占位符有效性及是否存在嵌套)

我自己实现了一个函数,但效率偏低,希望得到更优的实现方案:

public static List<string> GetInBrackets(string input)
{
    List<string> res = new List<string>();
    int bracketCount = 0;
    string tempStr = "";
    foreach (char c in input.ToCharArray())
    {
        if (bracketCount > 0)
        {
            tempStr += c.ToString();
        }
        if (c.ToString() == "{")
        {
            bracketCount++;
        }
        if (c.ToString() == "}")
        {
            bracketCount--;
            if (bracketCount == 0)
            {
                res.Add(tempStr.Substring(0,tempStr.Length-1));
                tempStr = "";
            }
        }
    }
    return res;
}

优化方案

1. 核心优化思路

原代码的主要性能瓶颈在于字符串拼接(string +=会频繁生成新字符串对象),以及冗余的字符转字符串操作。优化方向聚焦在内存效率、逻辑简化和错误兼容扩展性上。

2. 高效遍历实现(推荐)

使用StringBuilder处理临时字符串拼接,直接做字符比较减少转换开销,同时保留错误状态记录用于后续校验:

using System.Collections.Generic;
using System.Text;

public static List<string> GetPlaceholders(string input)
{
    List<string> placeholders = new List<string>();
    StringBuilder tempBuilder = new StringBuilder();
    int bracketDepth = 0;
    bool hasInvalidBrackets = false;

    foreach (char c in input)
    {
        if (c == '{')
        {
            bracketDepth++;
            // 嵌套的{需要加入占位符内容
            if (bracketDepth > 1)
            {
                tempBuilder.Append(c);
            }
            continue;
        }

        if (c == '}')
        {
            bracketDepth--;
            if (bracketDepth == 0)
            {
                // 闭合最外层{,提取占位符内容
                placeholders.Add(tempBuilder.ToString());
                tempBuilder.Clear();
            }
            else if (bracketDepth > 0)
            {
                // 嵌套的}加入占位符内容
                tempBuilder.Append(c);
            }
            else
            {
                // 出现无匹配的},标记错误
                hasInvalidBrackets = true;
            }
            continue;
        }

        // 非括号字符,仅在占位符内部时记录
        if (bracketDepth > 0)
        {
            tempBuilder.Append(c);
        }
    }

    // 遍历结束后仍有未闭合的{,标记错误
    if (bracketDepth > 0)
    {
        hasInvalidBrackets = true;
        // 可根据需求选择是否将未闭合的内容加入列表
        // placeholders.Add(tempBuilder.ToString());
    }

    // 后续可通过hasInvalidBrackets触发错误处理逻辑
    return placeholders;
}

3. 正则表达式实现(适合快速开发)

如果不需要极致性能,正则表达式可以用简洁代码实现嵌套匹配,但对错误格式的处理灵活性稍弱:

using System.Collections.Generic;
using System.Text.RegularExpressions;

public static List<string> GetPlaceholdersRegex(string input)
{
    List<string> placeholders = new List<string>();
    // 递归匹配最外层{},支持内部嵌套
    Regex regex = new Regex(@"\{(?>[^{}]+|\{(?<Depth>)|\}(?<-Depth>))*(?(Depth)(?!))\}", RegexOptions.Compiled);
    MatchCollection matches = regex.Matches(input);

    foreach (Match match in matches)
    {
        // 去除外层的{},提取占位符内容
        string content = match.Value.Substring(1, match.Value.Length - 2);
        placeholders.Add(content);
    }

    // 可额外扫描字符串中的异常括号(比如示例中的{APPTTIME])做错误处理
    return placeholders;
}

方案对比

  • 遍历方案:性能最优,适合长字符串、复杂嵌套场景,能灵活处理各类输入错误,便于自定义校验逻辑。
  • 正则方案:代码简洁,开发成本低,但极端嵌套或错误格式场景下的灵活性不足,性能略逊于遍历方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 11:47:44