求提取字符串中{}内占位符的高效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
相关产品推荐
相关产品推荐

