Изменение содержимого строки в C#

В этой статье демонстрируется несколько способов получения string путем изменения существующего объекта string. Все показанные методы возвращают результат изменений как новый объект string. Чтобы показать, что исходная и измененная строки являются отдельными экземплярами, в этих примерах результат сохраняется в новой переменной. При выполнении каждого примера можно изучить исходный string и новый, измененный string.

Примечание.

Примеры C# в этой статье выполняются во встроенном средстве выполнения кода и на площадке Try.NET. Нажмите на кнопку Выполнить, чтобы выполнить пример в интерактивном окне. После выполнения кода вы можете изменить его и выполнить измененный код, снова нажав на кнопку Выполнить. Либо в интерактивном окне выполняется измененный код, либо, если компиляция завершается с ошибкой, в интерактивном окне отображаются все сообщения об ошибках компилятора C#.

В статье приводится несколько методов. Вы можете заменять существующий текст. Вы можете искать шаблоны и заменять соответствующий текст другим. Вы можете рассматривать строку как последовательность символов. Вы также можете использовать удобные методы удаления пробелов. Выберите метод, наиболее подходящий для вашего сценария.

Заменить текст

Следующий код создает новую строку, заменяя существующий текст.

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

// Replace one substring with another with String.Replace.
// Only exact matches are supported.
var replacement = source.Replace("mountains", "peaks");
Console.WriteLine($"The source string is <{source}>");
Console.WriteLine($"The updated string is <{replacement}>");

В коде выше демонстрируется неизменяемое свойство строк. В примере видно, что исходная строка source не изменяется. Метод String.Replace создает новый объект string, содержащий изменения.

Метод Replace может заменять строки или отдельные символы. В обоих случаях заменяется каждое вхождение искомого текста. В следующем примере заменяются все символы ' на "_".

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

// Replace all occurrences of one char with another.
var replacement = source.Replace(' ', '_');
Console.WriteLine(source);
Console.WriteLine(replacement);

Исходная строка не изменяется. Возвращается новая строка с заменой.

Усечение пробелов

Используйте методы String.Trim, String.TrimStart и String.TrimEnd для удаления всех начальных или конечных пробелов. В приведенном ниже коде показан пример каждого метода. Исходная строка не изменяется. Эти методы возвращают новую строку с измененным содержимым.

// Remove trailing and leading white space.
string source = "    I'm wider than I need to be.      ";
// Store the results in a new string variable.
var trimmedResult = source.Trim();
var trimLeading = source.TrimStart();
var trimTrailing = source.TrimEnd();
Console.WriteLine($"<{source}>");
Console.WriteLine($"<{trimmedResult}>");
Console.WriteLine($"<{trimLeading}>");
Console.WriteLine($"<{trimTrailing}>");

Удалить текст

Вы можете удалять из строки текст с помощью метода String.Remove. Этот метод удаляет определенное число символов, начиная с указанного индекса. В следующем примере показано, как использовать String.IndexOf с Remove для удаления текста из строки:

string source = "Many mountains are behind many clouds today.";
// Remove a substring from the middle of the string.
string toRemove = "many ";
string result = string.Empty;
int i = source.IndexOf(toRemove);
if (i >= 0)
{
    result= source.Remove(i, toRemove.Length);
}
Console.WriteLine(source);
Console.WriteLine(result);

Замена совпадающих шаблонов

Используйте регулярные выражения для замены текста, соответствующего шаблонам, на новый текст, который может быть определен шаблоном. В следующем примере используется класс System.Text.RegularExpressions.Regex для поиска шаблона в исходной строке и замены его с правильным регистром. Метод Regex.Replace(String, String, MatchEvaluator, RegexOptions) принимает в качестве одного из аргументов функцию, которая предоставляет логику замены. В примере эта функция (LocalReplaceMatchCase) является локальной функцией и объявляется внутри демонстрируемого метода. LocalReplaceMatchCase использует класс System.Text.StringBuilder, чтобы создать замещающую строку с правильным регистром.

Регулярные выражения наиболее эффективны при поиске и замене текста, который соответствует шаблону, а не известного текста. Дополнительные сведения см. в практическом руководстве по поиску строк. Шаблон поиска "the\s" ищет слово "the", за которым следует пробел. Эта часть шаблона гарантирует пропуск слова "there" в исходной строке. Дополнительные сведения об элементах языка регулярных выражений см. в разделе Элементы языка регулярных выражений — краткий справочник.

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

// Use Regex.Replace for more flexibility.
// Replace "the" or "The" with "many" or "Many".
// using System.Text.RegularExpressions
string replaceWith = "many ";
source = System.Text.RegularExpressions.Regex.Replace(source, "the\\s", LocalReplaceMatchCase,
    System.Text.RegularExpressions.RegexOptions.IgnoreCase);
Console.WriteLine(source);

string LocalReplaceMatchCase(System.Text.RegularExpressions.Match matchExpression)
{
    // Test whether the match is capitalized
    if (Char.IsUpper(matchExpression.Value[0]))
    {
        // Capitalize the replacement string
        System.Text.StringBuilder replacementBuilder = new System.Text.StringBuilder(replaceWith);
        replacementBuilder[0] = Char.ToUpper(replacementBuilder[0]);
        return replacementBuilder.ToString();
    }
    else
    {
        return replaceWith;
    }
}

Метод StringBuilder.ToString возвращает неизменяемую строку с содержимым в объекте StringBuilder.

Изменение отдельных символов

Вы можете создать из строки массив символов, изменить содержимое массива, а затем создать из измененного содержимого новую строку.

В примере ниже показано, как заменить набор символов в строке. Сначала используется метод String.ToCharArray() для создания массива символов. Он использует IndexOf метод для поиска начального индекса слова "fox". Следующие три символа заменяются другим словом. Наконец, из обновленного массива символов создается новая строка.

string phrase = "The quick brown fox jumps over the fence";
Console.WriteLine(phrase);

char[] phraseAsChars = phrase.ToCharArray();
int animalIndex = phrase.IndexOf("fox");
if (animalIndex != -1)
{
    phraseAsChars[animalIndex++] = 'c';
    phraseAsChars[animalIndex++] = 'a';
    phraseAsChars[animalIndex] = 't';
}

string updatedPhrase = new string(phraseAsChars);
Console.WriteLine(updatedPhrase);

Программная сборка содержимого строки

Поскольку строки являются неизменяемыми, в предыдущих примерах создаются временные строки или массивы символов. В высокопроизводительных сценариях, возможно, будет целесообразным избежать этих распределений куч. .NET Core предоставляет метод String.Create, позволяющий программно заполнять символьное содержимое строки с помощью обратного вызова, избегая промежуточного распределения строк.

// constructing a string from a char array, prefix it with some additional characters
char[] chars = { 'a', 'b', 'c', 'd', '\0' };
int length = chars.Length + 2;
string result = string.Create(length, chars, (Span<char> strContent, char[] charArray) =>
{
    strContent[0] = '0';
    strContent[1] = '1';
    for (int i = 0; i < charArray.Length; i++)
    {
        strContent[i + 2] = charArray[i];
    }
});

Console.WriteLine(result);

Вы можете изменить строку в фиксированном блоке с использованием ненадежного кода, но крайне не рекомендует изменять содержимое строки после ее создания. Такая попытка приведет к непредсказуемым последствиям. Например, если кто-то развернет строку, имеющую то же содержимое, что и ваша строка, он получит копию вашей строки и не будет рассчитывать на то, что вы изменяете его строку.

См. также