【问题标题】:Replacing a char at a given index in string? [duplicate]替换字符串中给定索引处的字符? [复制]
【发布时间】:2017-04-09 04:40:53
【问题描述】:

String 没有ReplaceAt(),我对如何制作一个符合我需要的体面的函数有点犹豫。我想CPU成本很高,但字符串很小,所以没关系

【问题讨论】:

  • 你不是说“没有”而不是“有”吗? :)

标签: c# string


【解决方案1】:

使用StringBuilder

StringBuilder sb = new StringBuilder(theString);
sb[index] = newChar;
theString = sb.ToString();

【讨论】:

  • @Jason94,我不确定这是否比在 Jon 的回答中使用 ToCharArray 更有效,您应该运行测试以查看哪个更快。
  • 我在 10 万次迭代中尝试了一个小基准测试,ToCharArray 至少快了 2 倍。
  • new StringBuilder(theString) {[index] = newChar}.ToString(); 使用对象初始值设定项,您可以使其成为单行代码
【解决方案2】:

最简单的方法是这样的:

public static string ReplaceAt(this string input, int index, char newChar)
{
    if (input == null)
    {
        throw new ArgumentNullException("input");
    }
    char[] chars = input.ToCharArray();
    chars[index] = newChar;
    return new string(chars);
}

现在这是一种扩展方法,因此您可以使用:

var foo = "hello".ReplaceAt(2, 'x');
Console.WriteLine(foo); // hexlo

如果能想出某种方法,只需要制作一个单个数据副本而不是这里的两个副本,那就太好了,但我不确定有什么方法可以做到这一点。 有可能这样做:

public static string ReplaceAt(this string input, int index, char newChar)
{
    if (input == null)
    {
        throw new ArgumentNullException("input");
    }
    StringBuilder builder = new StringBuilder(input);
    builder[index] = newChar;
    return builder.ToString();
}

...我怀疑这完全取决于您使用的框架版本。

【讨论】:

  • +1 使其成为扩展方法。如已接受答案的评论和其他答案中所述, ToCharArray() 方法比 StringBuilder 方法快。另一个可能的改进:检查 input.Count > index-1 && index >= 0 否则当你执行 chars[index] 或 builder[index] 时会出现异常。
【解决方案3】:
string s = "ihj";
char[] array = s.ToCharArray();
array[1] = 'p';
s = new string(array);

【讨论】:

  • 接受的答案下的评论表明这种方法的速度是原来的两倍。
  • 更快更好。
【解决方案4】:

字符串是不可变的对象,因此您不能替换字符串中的给定字符。 您可以做的是创建一个替换给定字符的新字符串。

但是如果你要创建一个新字符串,为什么不使用 StringBuilder:

string s = "abc";
StringBuilder sb = new StringBuilder(s);
sb[1] = 'x';
string newS = sb.ToString();

//newS = "axc";

【讨论】:

    【解决方案5】:

    突然需要做这个任务,发现了这个话题。 所以,这是我的 linq 风格的变体:

    public static class Extensions
    {
        public static string ReplaceAt(this string value, int index, char newchar)
        {
            if (value.Length <= index)
                return value;
            else
                return string.Concat(value.Select((c, i) => i == index ? newchar : c));
        }
    }
    

    然后,例如:

    string instr = "Replace$dollar";
    string outstr = instr.ReplaceAt(7, ' ');
    

    最后我需要使用 .Net Framework 2,所以我使用了 StringBuilder 类变体。

    【讨论】:

    • 对于长字符串来说这不会很慢吗?为什么这样做,而不是StringBuilderToCharArray 解决方案?它可能是字符串的少一份副本(与 StringBuilder 相比),但我怀疑内部发生了很多事情。
    【解决方案6】:

    如果您的项目 (.csproj) 允许不安全代码,这可能是更快的解决方案:

    namespace System
    {
      public static class StringExt
      {
        public static unsafe void ReplaceAt(this string source, int index, char value)
        {
            if (source == null)
                throw new ArgumentNullException("source");
    
            if (index < 0 || index >= source.Length)
                throw new IndexOutOfRangeException("invalid index value");
    
            fixed (char* ptr = source)
            {
                ptr[index] = value;
            }
        }
      }
    }
    

    您可以将它用作String对象的扩展方法。

    【讨论】:

    • 当然,这违反了string 的语义 - 影响对该对象的任何其他引用,使string 对象是不可变的文档无效/矛盾。对于内置类,这样做是非常可疑的(强烈的代码气味)。需要一个巨大的警告评论。就个人而言,我不会这样做。如果有人需要一个可变字符串,那么创建一个适当的类,子类化或包装一个char[]
    【解决方案7】:
    public string ReplaceChar(string sourceString, char newChar, int charIndex)
        {
            try
            {
                // if the sourceString exists
                if (!String.IsNullOrEmpty(sourceString))
                {
                    // verify the lenght is in range
                    if (charIndex < sourceString.Length)
                    {
                        // Get the oldChar
                        char oldChar = sourceString[charIndex];
    
                        // Replace out the char  ***WARNING - THIS CODE IS WRONG - it replaces ALL occurrences of oldChar in string!!!***
                        sourceString.Replace(oldChar, newChar);
                    }
                }
            }
            catch (Exception error)
            {
                // for debugging only
                string err = error.ToString();
            }
    
            // return value
            return sourceString;
        }
    

    【讨论】:

    • sourceString.Replace(oldChar, newChar) 替换字符串中所有出现的 oldChar,而不仅仅是 charIndex 处的字符。
    • 字符串错误 = error.ToString();为什么?
    猜你喜欢
    • 1970-01-01
    • 2011-10-20
    • 1970-01-01
    • 2017-01-14
    • 1970-01-01
    • 1970-01-01
    • 2021-05-31
    • 2013-03-04
    相关资源
    最近更新 更多