在 C 中修改字符串内容#

Tip

本文是已了解至少一种编程语言并正在学习 C# 的开发人员的 “基础知识 ”部分的一部分。 如果你不熟悉编程,请先 学习入门 教程。

来自另一种语言? 与Java和 JavaScript 一样,C# 字符串是不可变的:方法(例如ReplaceTrim返回新字符串),而不是更改原始字符串。 这里的模式与那些语言中的 String 方法相对应。

C# string 是不 可变的,这意味着其内容在创建后永远不会更改。 每个看似会修改字符串的方法,实际上都会返回一个包含这些更改的新 string,而原始字符串保持不变。 本文中的示例将每个结果存储在一个新变量中,以便查看源和修改后的值。

选择与方案匹配的技术:替换已知文本、剪裁空格、删除字符范围、替换与模式匹配的文本或编辑单个字符。

替换已知文本

该方法 String.Replace 将一个字符串的每个匹配项替换为另一个字符串,并将结果作为新字符串返回:

string source = "The mountains are behind the clouds today.";

// Replace returns a new string; the original is unchanged.
string updated = source.Replace("mountains", "peaks");

Console.WriteLine(source);
// => The mountains are behind the clouds today.
Console.WriteLine(updated);
// => The peaks are behind the clouds today.

原始字符串保持不变,它演示不可变性: Replace 使用替换创建新字符串。

Replace 还有一个用于交换单个字符的重载。 以下示例用下划线替换每个空格:

string source = "The mountains are behind the clouds today.";

// Replace every occurrence of one character with another.
string updated = source.Replace(' ', '_');

Console.WriteLine(updated);
// => The_mountains_are_behind_the_clouds_today.

这两个重载都会替换字符串中的每个匹配项,而不仅仅是第一个匹配项。 无论传入的是单个字符还是字符串,Replace 都会在一次调用中替换所有出现的位置。

剪裁空格

使用 String.TrimString.TrimStartString.TrimEnd 删除前导或尾随空白。 每个方法返回一个新字符串:

string source = "    I'm wider than I need to be.      ";

// Each method returns a new string with whitespace removed.
Console.WriteLine($"<{source.Trim()}>");
// => <I'm wider than I need to be.>
Console.WriteLine($"<{source.TrimStart()}>");
// => <I'm wider than I need to be.      >
Console.WriteLine($"<{source.TrimEnd()}>");
// => <    I'm wider than I need to be.>

删除一段字符

String.Remove 方法从指定索引开始删除多个字符。 将其与 String.IndexOf 结合使用,以定位要删除的文本:

string source = "Many mountains are behind many clouds today.";
string toRemove = "many ";

// Find the text, then remove that span by index and length.
int index = source.IndexOf(toRemove);
string result = index >= 0
    ? source.Remove(index, toRemove.Length)
    : source;

Console.WriteLine(result);
// => Many mountains are behind clouds today.

替换与模式匹配的文本

当需要替换遵循模式而不是确切字符串的文本时,请使用 正则表达式Regex.Replace 方法接受一个用于计算每个替换内容的函数,因此你可以保留诸如原始大小写形式等细节。 该模式 the\s 匹配后面跟着空白字符的“the”,因此不会匹配“there”:

string source = "The mountains are still there behind the clouds today.";

// Replace "the" or "The" followed by whitespace, preserving the original case.
// The \s in the pattern keeps "there" from matching.
string result = Regex.Replace(
    source,
    """the\s""",
    match => char.IsUpper(match.Value[0]) ? "Many " : "many ",
    RegexOptions.IgnoreCase);

Console.WriteLine(result);
// => Many mountains are still there behind many clouds today.

有关基于模式的搜索,而不是替换,请参阅 C# 中的搜索字符串。 有关正则表达式语法,请参阅 正则表达式语言快速参考

修改单个字符

若要按位置更改字符,请将字符串复制到字符中 Span<T> ,修改范围,然后从中生成一个新字符串。 以下示例查找单词“fox”并将其替换为“cat”:

string phrase = "The quick brown fox jumps over the fence.";

// A string is immutable, so copy it into a Span<char> to edit in place.
Span<char> characters = stackalloc char[phrase.Length];
phrase.CopyTo(characters);
int index = phrase.IndexOf("fox");
if (index != -1)
{
    characters[index] = 'c';
    characters[index + 1] = 'a';
    characters[index + 2] = 't';
}

// Build a new string from the modified characters.
string updated = new string(characters);
Console.WriteLine(updated);
// => The quick brown cat jumps over the fence.

对于避免中间分配的高性能方案,运行时提供较低级别的 API,例如 String.Create。 这些技术是高级的;对于日常代码,本文中的方法是正确的选择。

另见