Introduction
This article demonstrates several techniques to produce a string by modifying an existing string. All the techniques demonstrated return the result of the modifications as a new string object. To demonstrate that the original and modified strings are distinct instances, the examples store the result in a new variable. You can examine the original string and the new, modified string when you run each example.
Replace text
The following code creates a new string by replacing existing text with a substitute.
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}>");
// o/p: The source string is <The mountains are behind the clouds today.>
// o/p: The updated string is <The peaks are behind the clouds today.>
The preceding code demonstrates this immutable property of strings. You can see in the preceding example that the original string, source, is not modified. The String.Replace method creates a new string containing the modifications.
The Replace method can replace either strings or single characters. In both cases, every occurrence of the sought text is replaced. The following example replaces all ' ' characters with '_':
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);
//o/p: The mountains are behind the clouds today.
//o/p: The_mountains_are_behind_the_clouds_today
The source string is unchanged, and a new string is returned with the replacement.
Trim white space
You can use the String.Trim, String.TrimStart, and String.TrimEnd methods to remove any leading or trailing white space. The following code shows an example of each. The source string does not change; these methods return a new string with the modified contents.
// 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}>");
//o/p: < I'm wider than I need to be. >
//o/p: <I'm wider than I need to be.>
//o/p: <I'm wider than I need to be. >
//o/p: < I'm wider than I need to be.>
Remove text
You can remove text from a string using the String.Remove method. This method removes a number of characters starting at a specific index. The following example shows how to use String.IndexOf followed by Remove to remove text from a string:
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);
//o/p: Many mountains are behind many clouds today.
//o/p: Many mountains are behind clouds today.
Replace matching patterns
You can use regular expressions to replace text-matching patterns with new text, possibly defined by a pattern. The following example uses the System.Text.RegularExpressions.Regex class to find a pattern in a source string and replace it with proper capitalization. The Regex.Replace(String, String, MatchEvaluator, RegexOptions) method takes a function that provides the logic of the replacement as one of its arguments. In this example, that function, LocalReplaceMatchCase is a local function declared inside the sample method. LocalReplaceMatchCase uses the System.Text.StringBuilder class to build the replacement string with proper capitalization.
Regular expressions are most useful for searching and replacing text that follows a pattern rather than known text. For more information, see How to search strings. The search pattern "the\s" searches for the word "the" followed by a white-space character. That part of the pattern ensures that it doesn't match "there" in the source string. For more information on regular expression language elements, see Regular Expression Language - Quick Reference.
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;
}
}
//o/p: Many mountains are still there behind many clouds today.
The StringBuilder.ToString method returns an immutable string with the contents in the StringBuilder object.
Modifying individual characters
You can produce a character array from a string, modify the contents of the array, and then create a new string from the modified contents of the array.
The following example shows how to replace a set of characters in a string. First, it uses the String.ToCharArray() method to create an array of characters. It uses the IndexOf method to find the starting index of the word "fox." The next three characters are replaced with a different word. Finally, a new string is constructed from the updated character array.
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);
//o/p: The quick brown fox jumps over the fence
//o/p: The quick brown cat jumps over the fence
Programmatically build up string content
Since strings are immutable, the previous examples all create temporary strings or character arrays. In high-performance scenarios, it may be desirable to avoid these heap allocations. .NET Core provides a String.Create method that allows you to programmatically fill in the character content of a string via a callback while avoiding the intermediate temporary string allocations.
// 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);
//o/p: 01abcd
You could modify a string in a fixed block with unsafe code, but it is strongly discouraged to modify the string content after a string is created. Doing so will break things in unpredictable ways. For example, if someone interns a string that has the same content as yours, they'll get your copy and won't expect that you are modifying their string.
Conclusion
This article has illustrated various techniques for producing modified strings from existing ones in C#. Each method showcased here returns the result of the modifications as a new string object, emphasizing the immutable nature of strings in C#. By storing the modified strings in new variables, the examples clearly demonstrate that the original and modified strings are distinct instances. This distinction underscores the importance of understanding string immutability in C# and highlights the need to create new string objects when making modifications. By following these techniques, developers can effectively manipulate string data while ensuring data integrity and avoiding unexpected side effects.