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); }
正确实现方案
核心思路:
- 头部遍历:逐个检查字符,优先匹配完整片段,再匹配单个修剪字符,匹配成功则跳过对应长度,直到遇到非修剪内容
- 尾部遍历:从末尾反向检查,逻辑与头部一致,匹配成功则向前跳过对应长度
- 最终根据遍历结果截取子串,同时统计首尾修剪的字符数
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; }
测试验证
针对问题中的测试用例:
- 输入
"///g, hhh/ , test":- 头部匹配
//(前2个字符),修剪2个字符;剩余的/不属于修剪范围,停止头部修剪 - 最终结果:
"/g, hhh/ , test",头部修剪2个字符,尾部修剪0个
- 头部匹配
- 输入
"/*g, hhh/ , test":- 头部匹配
/*(前2个字符),修剪2个字符;后续的g不符合修剪条件,停止头部修剪 - 最终结果:
"g, hhh/ , test",头部修剪2个字符,尾部修剪0个
- 头部匹配
内容的提问来源于stack exchange,提问作者Unable error
相关产品推荐
相关产品推荐

