Tengo un problema en el que necesito reemplazar la última aparición de una palabra en una cadena.
Situación: me dan una cadena que tiene este formato:
string filePath ="F:/jan11/MFrame/Templates/feb11";
Luego reemplazo TnaNameasí:
filePath = filePath.Replace(TnaName, ""); // feb11 is TnaName
Esto funciona, pero tengo un problema cuando TnaNamees el mismo que mi folder name. Cuando esto sucede, termino obteniendo una cadena como esta:
F:/feb11/MFrame/Templates/feb11
Ahora ha reemplazado ambas apariciones de TnaNamecon feb11. ¿Hay alguna forma de que pueda reemplazar solo la última aparición de la palabra en mi cadena?
Nota: feb11es lo TnaNameque proviene de otro proceso, eso no es un problema.

/adelante?)TnaNamehay más en la ruta, pero solo genero una muestra para la pregunta.Gracias.Respuestas:
Aquí está la función para reemplazar la última aparición de una cadena
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; }Sourcees la cadena en la que desea realizar la operación.Findes la cadena que desea reemplazar.Replacees la cadena con la que desea reemplazarla.fuente
Place == -1)public static string ReplaceLastOccurance(this string Source...y tendrá un método de extensión ingenioso que puede usar para reemplazar la última aparición de una cadena para cualquier cadena.Use
string.LastIndexOf()para encontrar el índice de la última aparición de la cadena y luego use la subcadena para buscar su solución.fuente
Tienes que hacer el reemplazo manualmente:
int i = filePath.LastIndexOf(TnaName); if (i >= 0) filePath = filePath.Substring(0, i) + filePath.Substring(i + TnaName.Length);fuente
No veo por qué no se puede usar Regex:
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); }Uso:
string filePath ="F:/feb11/MFrame/Templates/feb11"; filePath = filePath.RemoveEnd("feb11"); // F:/feb11/MFrame/Templates/ filePath = filePath.ReplaceEnd("feb11","jan11"); // F:/feb11/MFrame/Templates/jan11fuente
return Regex.Replace(Regex.Replace(source),pattern, replacement);?Puede usar una
Pathclase delSystem.IOespacio de nombres:string filePath = "F:/jan11/MFrame/Templates/feb11"; Console.WriteLine(System.IO.Path.GetDirectoryName(filePath));fuente
La solución se puede implementar aún más simple con una sola línea:
static string ReplaceLastOccurrence(string str, string toReplace, string replacement) { return Regex.Replace(str, $@"^(.*){toReplace}(.*?)$", $"$1{replacement}$2"); }De este modo, aprovechamos la codicia del operador de asterisco regex. La función se usa así:
var s = "F:/feb11/MFrame/Templates/feb11"; var tnaName = "feb11"; var r = ReplaceLastOccurrence(s,tnaName, string.Empty);fuente
var lastIndex = filePath.LastIndexOf(TnaName); filePath = filePath.Substring(0, lastIndex);fuente