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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 15:06:24