C#实现保留字符串指定字符首次出现、移除其余同字符
C# 移除指定字符除首次出现外所有实例的实现
问题场景
需求为移除字符串中指定字符除首次出现外的所有实例,示例如下:
string original = "foo bar foo $ bar $ foo bar $ "; string desired_output = "foo bar foo $ bar foo bar";
原有实现代码运行结果不符合预期,错误代码如下:
string s = "foo bar foo $ bar $ foo bar $ "; char ch = '$'; for (int i = 0; i < s.Length; i++) { if (s[i] == ch) { s = s.Substring(0, i) + s.Substring(i + 1); break; } } for (int i = s.Length - 1; i > -1; i--) { if (s[i] == ch) { s = s.Substring(0, i) + s.Substring(i + 1); break; } } Console.WriteLine(s);
上述代码实际输出为foo bar foo bar $ foo bar,没有正确保留第一个$,也没有移除全部多余的$字符。
错误原因
原有代码逻辑存在本质问题:
- 第一段正向循环找到第一个
$后直接将其删除,恰好删掉了需要保留的首个目标字符 - 两段循环都只执行一次删除操作就
break,总共仅删除2个$,无法清除所有多余的目标字符 - 反复通过
Substring拼接新字符串,处理长字符串时效率极低
正确实现
基础遍历写法(适合初学者理解)
通过标记位记录是否已经遇到过首个目标字符,逐字符判断是否保留,使用StringBuilder提升拼接效率:
using System.Text; // 引入StringBuilder所在命名空间 string s = "foo bar foo $ bar $ foo bar $ "; char target = '$'; bool hasMetFirstTarget = false; StringBuilder sb = new StringBuilder(); foreach (char c in s) { if (c == target) { // 是目标字符,仅在第一次遇到时保留 if (!hasMetFirstTarget) { sb.Append(c); hasMetFirstTarget = true; } // 非首次遇到的目标字符直接跳过 continue; } // 非目标字符直接保留 sb.Append(c); } // 调用Trim()清除首尾多余空格,和示例期望输出完全匹配 string result = sb.ToString().Trim(); Console.WriteLine(result); // 输出:foo bar foo $ bar foo bar
简洁LINQ写法
熟悉LINQ语法可以用更精简的代码实现相同逻辑:
string s = "foo bar foo $ bar $ foo bar $ "; char target = '$'; int count = 0; string result = new string(s.Where(c => c != target || ++count == 1).ToArray()).Trim(); Console.WriteLine(result);
逻辑为:遍历字符时仅保留两类字符——非目标字符、第一次命中的目标字符,其余字符全部过滤。
内容的提问来源于stack exchange,提问作者BogdanNetan
相关产品推荐
相关产品推荐

