Back to Blog
C#

C# String Replace: Syntax, Overloads, and Performance

Learn how to use C# string.Replace, including string and character overloads, all-occurrence behavior, case sensitivity, performance tradeoffs, and when to choose Regex or StringBuilder.

string manipulationC# methodsRegexStringBuilderperformance
Illustration of C# string replace operation showing substring substitution

The string.Replace method in C# replaces all occurrences of a character or substring with another character or substring. The simplest overloads take two characters or two strings:

string text = "Hello, World!"; string replaced = text.Replace("World", "C#"); // replaced == "Hello, C#!"

The character overload works similarly but replaces single characters with a single character.

Replacing All Occurrences vs. First Occurrence

Replace replaces every occurrence of the search value, not just the first. If you need to replace only the first occurrence, you have to write that logic yourself, for example with IndexOf and Substring:

string text = "one two one three"; int index = text.IndexOf("one"); string firstReplaced = index >= 0 ? text.Substring(0, index) + "1" + text.Substring(index + "one".Length) : text;

This works when you want one specific first match. If you need to replace the first occurrence of several different strings, a StringBuilder loop is easier to maintain.

Case Sensitivity and Culture

The string and char overloads of Replace use ordinal, case-sensitive, and culture-insensitive matching: they treat "abc" and "ABC" as different. For case-insensitive replacement in current .NET, use the StringComparison overload:

string result = text.Replace("hello", "hi", StringComparison.OrdinalIgnoreCase);

On .NET Framework, or when you need regular-expression matching, use Regex.Replace with RegexOptions.IgnoreCase:

using System.Text.RegularExpressions; string text = "Hello hello HELLO"; string result = Regex.Replace(text, "hello", "hi", RegexOptions.IgnoreCase);

Both approaches replace all case variants of "hello" with "hi". Regex is more flexible when you need patterns rather than literal strings; for literal case-insensitive text replacement, the StringComparison overload is simpler and does not treat the replacement text as a pattern.

Performance Considerations

Strings are immutable, so string.Replace returns a new string. For a single replacement that is fine. If you perform many replacements in a loop, repeated calls allocate many intermediate strings. StringBuilder.Replace modifies the builder's buffer and is usually more efficient for repeated replacements on the same text:

var sb = new StringBuilder("Hello, World!"); sb.Replace("World", "C#"); string result = sb.ToString();

StringBuilder.Replace also replaces all occurrences and uses the same ordinal, case-sensitive matching. The benefit is clearest when you apply several replacements to the same text before converting it to a final string.

Alternatives: Regex.Replace and StringBuilder

Regex.Replace is the right choice for pattern matching, complex transformations, or case-insensitive replacement on .NET Framework. It is more flexible but has regex parsing and matching overhead. StringBuilder.Replace is useful for repeated replacements on the same buffer. The table summarizes the tradeoffs:

ApproachUse whenPerformance
string.ReplaceSimple, all-occurrence replacementFast for one-off; allocates a new string
StringBuilder.ReplaceMany replacements on one bufferIn-place, fewer allocations
Regex.ReplacePattern-based or complex matchingSlower, but flexible

For a one-time replacement, string.Replace is clear and efficient. For several replacements on the same text, StringBuilder avoids repeated allocations. For regex patterns, regex is the practical choice.

Common Pitfalls and Edge Cases

Replace throws ArgumentNullException if the search value is null. An empty search value is allowed and returns the original string unchanged. Replacement scans left to right and does not handle overlapping matches:

string text = "aaa"; string result = text.Replace("aa", "b"); // result is "ba": the first two 'a' are replaced, then the third remains.

This behavior is worth remembering when your search values could overlap.

Practical Example: Replacing Placeholders in a Template

A common use case is replacing placeholders in a template string. Because Replace returns a new string, calls can be chained:

string template = "Hello {name}, welcome to {company}!"; string result = template.Replace("{name}", "Alice").Replace("{company}", "Contoso");

For a small, fixed set of placeholders, chaining is readable and efficient. For a dynamic set, keep the replacements in a dictionary and loop:

var replacements = new Dictionary<string, string> { ["{name}"] = "Alice", ["{company}"] = "Contoso" }; string result = template; foreach (var kvp in replacements) { result = result.Replace(kvp.Key, kvp.Value); }

This keeps the replacement logic in one place, especially when the placeholder list comes from configuration or user input.

C# String.Replace: Syntax, Overloads, and Alternatives | RYUSLOG DEV