121

I want to replace the first occurrence in a given string.

How can I accomplish this in .NET?

Blue
  • 22,608
  • 7
  • 62
  • 92
  • Please make clear posts that people can understand. I edited this one for you too. You should have specified a language at least here. – GEOCHET Sep 26 '08 at 18:13
  • Of course, it's never *replaced*... it is always a new string containing the original one with replaced text. This is because string are immutable. – Pablo Marambio Mar 02 '10 at 13:56
  • i tried the ` String.Replace()` method. but it replaces all the "AA" with "XQ" – Thorin Oakenshield Nov 03 '10 at 11:59
  • 2
    this question - http://stackoverflow.com/questions/141045/how-do-i-replace-a-string-in-net - reveals everything about what you need to do – stack72 Nov 03 '10 at 12:00
  • Are you always replacing the first two characters of the string? Or are there some strings that don't begin with 'AA'? Are there times when you need to replace 'AA' but it appears in the middle of the string (like "YZAA123" -> "YZXQ123")? – Matt Bridges Nov 03 '10 at 12:00
  • 1
    Note: merging with another similar question that used "AA" => "XQ" as the examples to find/replace. – Marc Gravell Nov 03 '10 at 12:23
  • @Marc Gravell - Shouldn't this question be tagged as C# as well? – Shadow The GPT Wizard Nov 03 '10 at 14:09

15 Answers15

152
string ReplaceFirst(string text, string search, string replace)
{
  int pos = text.IndexOf(search);
  if (pos < 0)
  {
    return text;
  }
  return text.Substring(0, pos) + replace + text.Substring(pos + search.Length);
}

Example:

string str = "The brown brown fox jumps over the lazy dog";

str = ReplaceFirst(str, "brown", "quick");

EDIT: As @itsmatt mentioned, there's also Regex.Replace(String, String, Int32), which can do the same, but is probably more expensive at runtime, since it's utilizing a full featured parser where my method does one find and three string concatenations.

EDIT2: If this is a common task, you might want to make the method an extension method:

public static class StringExtension
{
  public static string ReplaceFirst(this string text, string search, string replace)
  {
     // ...same as above...
  }
}

Using the above example it's now possible to write:

str = str.ReplaceFirst("brown", "quick");
Community
  • 1
  • 1
VVS
  • 19,405
  • 5
  • 46
  • 65
  • 4
    Beware: This doesn't work properly with Unicode combining characters or ligatures. For example, `ReplaceFirst("oef", "œ", "i")` incorrectly returns "ief" instead of "if". See [this question](http://stackoverflow.com/q/20480016/1127114) for more info. – Michael Liu Nov 17 '14 at 03:28
70

As itsmatt said Regex.Replace is a good choice for this however to make his answer more complete I will fill it in with a code sample:

using System.Text.RegularExpressions;
...
Regex regex = new Regex("foo");
string result = regex.Replace("foo1 foo2 foo3 foo4", "bar", 1);             
// result = "bar1 foo2 foo3 foo4"

The third parameter, set to 1 in this case, is the number of occurrences of the regex pattern that you want to replace in the input string from the beginning of the string.

I was hoping this could be done with a static Regex.Replace overload but unfortunately it appears you need a Regex instance to accomplish it.

Wes Haggard
  • 4,284
  • 1
  • 22
  • 21
  • 1
    That works for literal `"foo"`, but you're going to want a `new Regex(Regex.Escape("foo"))` for figurative `"foo"`. – ruffin Apr 28 '18 at 02:52
  • @ruffin: What's the difference between literal "foo" and figurative "foo"? Please explain. – priyamtheone Jun 20 '23 at 22:34
  • @priyamtheone If you were _literally searching for the string `"foo"`_, what we have works. But, usually, [`foo` is a standin](https://stackoverflow.com/a/58617/1028230), here meaning, it could be ***ANY*** string. There are strings (eg `"[(.*?)]"`) that could contain regex characters that [require escaping with `.Escape`](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.escape?view=net-7.0). Using that page's example, `Regex regex = new Regex("[(.*?)]")` is not equal to `Regex regex = new Regex(Regex.Escape("[") + "(.*?)]")` -- see the previous link for why. – ruffin Jun 21 '23 at 13:08
17

Take a look at Regex.Replace.

itsmatt
  • 31,265
  • 10
  • 100
  • 164
  • 2
    Specifically, Regex.Replace Method (String, String, Int32) will do the trick and is really concise. – itsmatt Sep 26 '08 at 18:32
16
using System.Text.RegularExpressions;

RegEx MyRegEx = new RegEx("F");
string result = MyRegex.Replace(InputString, "R", 1);

will find first F in InputString and replace it with R.

Alan Moore
  • 73,866
  • 12
  • 100
  • 156
Deenesh
  • 161
  • 1
  • 2
16

Taking the "first only" into account, perhaps:

int index = input.IndexOf("AA");
if (index >= 0) output = input.Substring(0, index) + "XQ" +
     input.Substring(index + 2);

?

Or more generally:

public static string ReplaceFirstInstance(this string source,
    string find, string replace)
{
    int index = source.IndexOf(find);
    return index < 0 ? source : source.Substring(0, index) + replace +
         source.Substring(index + find.Length);
}

Then:

string output = input.ReplaceFirstInstance("AA", "XQ");
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
11

C# extension method that will do this:

public static class StringExt
{
    public static string ReplaceFirstOccurrence(this string s, string oldValue, string newValue)
    {
         int i = s.IndexOf(oldValue);
         return s.Remove(i, oldValue.Length).Insert(i, newValue);    
    } 
}
Kech101
  • 5
  • 2
mortenbpost
  • 1,687
  • 16
  • 22
  • 1
    Thanks! I modified this to make a "RemoveFirst" extension method which... removes the first occurrence of a character from a string. – pbh101 Feb 11 '09 at 01:53
  • 4
    This will fail if oldValue isn't part of the string. – VVS Mar 02 '10 at 07:59
9

In C# syntax:

int loc = original.IndexOf(oldValue);
if( loc < 0 ) {
    return original;
}
return original.Remove(loc, oldValue.Length).Insert(loc, newValue);
Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
5

Assumes that AA only needs to be replaced if it is at the very start of the string:

var newString;
if(myString.StartsWith("AA"))
{
  newString ="XQ" + myString.Substring(2);
}

If you need to replace the first occurrence of AA, whether the string starts with it or not, go with the solution from Marc.

Oded
  • 489,969
  • 99
  • 883
  • 1,009
3

And because there is also VB.NET to consider, I would like to offer up:

Private Function ReplaceFirst(ByVal text As String, ByVal search As String, ByVal replace As String) As String
    Dim pos As Integer = text.IndexOf(search)
    If pos >= 0 Then
        Return text.Substring(0, pos) + replace + text.Substring(pos + search.Length)
    End If
    Return text 
End Function
Anthony Potts
  • 8,842
  • 8
  • 41
  • 56
3

One of the overloads of Regex.Replace takes an int for "The maximum number of times the replacement can occur". Obviously, using Regex.Replace for plain text replacement may seem like overkill, but it's certainly concise:

string output = (new Regex("AA")).Replace(input, "XQ", 1);
AakashM
  • 62,551
  • 17
  • 151
  • 186
3

For anyone that doesn't mind a reference to Microsoft.VisualBasic, there is the Replace Method:

string result = Microsoft.VisualBasic.Strings.Replace("111", "1", "0", 2, 1); // "101"
Slai
  • 22,144
  • 5
  • 45
  • 53
1

This example abstracts away the substrings (but is slower), but is probably much fast than a RegEx:

var parts = contents.ToString().Split(new string[] { "needle" }, 2, StringSplitOptions.None);
return parts[0] + "replacement" + parts[1];
0

Updated extension method utilizing Span to minimize new string creation

    public static string ReplaceFirstOccurrence(this string source, string search, string replace) {
        int index = source.IndexOf(search);
        if (index < 0) return source;
        var sourceSpan = source.AsSpan();
        return string.Concat(sourceSpan.Slice(0, index), replace, sourceSpan.Slice(index + search.Length));
    }
Brad Patton
  • 4,007
  • 4
  • 34
  • 44
0

With ranges and C# 10 we can do:

public static string ReplaceFirst(this string text, string search, string replace)
{
    int pos = text.IndexOf(search, StringComparison.Ordinal);
    return pos < 0 ? text : string.Concat(text[..pos], replace, text.AsSpan(pos + search.Length));
}
Matěj Štágl
  • 870
  • 1
  • 9
  • 27
-1
string abc = "AAAAX1";

            if(abc.IndexOf("AA") == 0)
            {
                abc.Remove(0, 2);
                abc = "XQ" + abc;
            }