Replace the last occurrence of a word in a string - C#

C#asp.net

C# Problem Overview


I have a problem where I need to replace the last occurrence of a word in a string.

Situation: I am given a string which is in this format:

string filePath ="F:/jan11/MFrame/Templates/feb11";

I then replace TnaName like this:

filePath = filePath.Replace(TnaName, ""); // feb11 is TnaName

This works, but I have a problem when TnaName is the same as my folder name. When this happens I end up getting a string like this:

F:/feb11/MFrame/Templates/feb11

Now it has replaced both occurrences of TnaName with feb11. Is there a way that I can replace only the last occurrence of the word in my string?

Note: feb11 is TnaName which comes from another process - that's not a problem.

C# Solutions


Solution 1 - C#

Here is the function to replace the last occurrence of a string

public static string ReplaceLastOccurrence(string Source, string Find, string Replace)
{
        int place = Source.LastIndexOf(Find);
        
        if(place == -1)
           return Source;
           
        string result = Source.Remove(place, Find.Length).Insert(place, Replace);
        return result;
}
  • Source is the string on which you want to do the operation.
  • Find is the string that you want to replace.
  • Replace is the string that you want to replace it with.

Solution 2 - C#

Use string.LastIndexOf() to find the index of the last occurrence of the string and then use substring to look for your solution.

Solution 3 - C#

You have to do the replace manually:

int i = filePath.LastIndexOf(TnaName);
if (i >= 0)
    filePath = filePath.Substring(0, i) + filePath.Substring(i + TnaName.Length);

Solution 4 - C#

I don't see why Regex can't be used:

public static string RegexReplace(this string source, string pattern, string replacement)
{
  return Regex.Replace(source,pattern, replacement);
}

public static string ReplaceEnd(this string source, string value, string replacement)
{
  return RegexReplace(source, $"{value}$", replacement);
}

public static string RemoveEnd(this string source, string value)
{
  return ReplaceEnd(source, value, string.Empty);
}

Usage:

string filePath ="F:/feb11/MFrame/Templates/feb11";
filePath = filePath.RemoveEnd("feb11"); // F:/feb11/MFrame/Templates/
filePath = filePath.ReplaceEnd("feb11","jan11"); // F:/feb11/MFrame/Templates/jan11

Solution 5 - C#

The solution can be implemented even more simple with a single line:

 static string ReplaceLastOccurrence(string str, string toReplace, string replacement)
    {
        return Regex.Replace(str, $@"^(.*){Regex.Escape(toReplace)}(.*?)$", $"$1{Regex.Escape(replacement)}$2");
    }

Hereby we take advantage of the greediness of the regex asterisk operator. The function is used like this:

var s = "F:/feb11/MFrame/Templates/feb11";
var tnaName = "feb11";
var r = ReplaceLastOccurrence(s,tnaName, string.Empty);

Solution 6 - C#

You can use a Path class from System.IO namepace:

string filePath = "F:/jan11/MFrame/Templates/feb11";

Console.WriteLine(System.IO.Path.GetDirectoryName(filePath));

Solution 7 - C#

The following doesn't replace TnaName in the path/string, but instead returns it without TnaName included:

var lastIndex = filePath.LastIndexOf(TnaName); // get position of TnaName

filePath = filePath.Substring(0, lastIndex); // get path till position of TnaName

Solution 8 - C#

The following function splits a string where the pattern (word to be replaced) last occurs.
Then it changes the pattern with the replacement string (in the second half of the string).
Finally, it concatenates both string halves back with each other again.

using System.Text.RegularExpressions;

public string ReplaceLastOccurance(string source, string pattern, string replacement)
{
   int splitStartIndex = source.LastIndexOf(pattern, StringComparison.OrdinalIgnoreCase);
   string firstHalf = source.Substring(0, splitStartIndex);
   string secondHalf = source.Substring(splitStartIndex, source.Length - splitStartIndex);
   secondHalf = Regex.Replace(secondHalf, pattern, replacement, RegexOptions.IgnoreCase);

   return firstHalf + secondHalf;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Question4b0View Question on Stackoverflow
Solution 1 - C#Behroz SikanderView Answer on Stackoverflow
Solution 2 - C#MontycarloView Answer on Stackoverflow
Solution 3 - C#Mohammad DehghanView Answer on Stackoverflow
Solution 4 - C#toddmoView Answer on Stackoverflow
Solution 5 - C#MarcBaltaView Answer on Stackoverflow
Solution 6 - C#Yuriy RozhovetskiyView Answer on Stackoverflow
Solution 7 - C#Kai HartmannView Answer on Stackoverflow
Solution 8 - C#MiminaView Answer on Stackoverflow