¿Cómo reemplazo la * primera instancia * de una cadena en .NET?

Quiero reemplazar la primera ocurrencia en una cadena dada.

¿Cómo puedo lograr esto en .NET?

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); } 

Ejemplo:

 string str = "The brown brown fox jumps over the lazy dog"; str = ReplaceFirst(str, "brown", "quick"); 

EDITAR : Como @itsmatt mencionado , también hay Regex.Replace (String, String, Int32), que puede hacer lo mismo, pero es probablemente más costoso en tiempo de ejecución, ya que está utilizando un analizador completo donde mi método hace uno y tres cadenas concatenaciones.

EDIT2 : si esta es una tarea común, es posible que desee convertir el método en un método de extensión:

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

Usando el ejemplo anterior ahora es posible escribir:

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

Como dice que Regex.Replace es una buena opción para esto, para que su respuesta sea más completa la completaré con una muestra de código:

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

El tercer parámetro, establecido en 1 en este caso, es el número de apariciones del patrón de expresiones regulares que desea reemplazar en la cadena de entrada desde el comienzo de la cadena.

Esperaba que esto se pudiera hacer con Regex estática. Reemplazar la sobrecarga pero, desafortunadamente, parece que necesitas una instancia de Regex para lograrlo.

Eche un vistazo a Regex.Replace .

Teniendo en cuenta “el primero”, quizás:

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

?

O más en general:

 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); } 

Entonces:

 string output = input.ReplaceFirstInstance("AA", "XQ"); 
 using System.Text.RegularExpressions; RegEx MyRegEx = new RegEx("F"); string result = MyRegex.Replace(InputString, "R", 1); 

encontrará primero F en InputString y lo reemplazará con R

En syntax C #:

 int loc = original.IndexOf(oldValue); if( loc < 0 ) { return original; } return original.Remove(loc, oldValue.Length).Insert(loc, newValue); 

Método de extensión C # que hará esto:

 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); } } 

Disfrutar

Y como también hay que considerar VB.NET, me gustaría ofrecer lo siguiente:

 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 

Supone que AA solo necesita ser reemplazado si está al comienzo de la cadena:

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

Si necesita reemplazar la primera aparición de AA , ya sea que la cadena comience con ella o no, vaya con la solución de Marc.

Una de las sobrecargas de Regex.Replace toma una int para “La cantidad máxima de veces que puede ocurrir la sustitución”. Obviamente, usar Regex.Replace para reemplazar el texto sin formato puede parecer exagerado, pero ciertamente es conciso:

 string output = (new Regex("AA")).Replace(input, "XQ", 1); 

Para cualquiera que no le importe una referencia a Microsoft.VisualBasic , existe el Método Replace :

 string result = Microsoft.VisualBasic.Strings.Replace("111", "1", "0", 2, 1); // "101" 

Regex.Replace , especialmente RegEx.Replace (cadena, cadena, int), es probablemente lo que estás buscando. Ese o String.IndexOf le dará el índice y luego puede cortar y reconstruir la cadena con el nuevo texto que desee.

Un ejemplo que demuestra lo último (como lo demostró por primera vez @David Humpohl ):

 string str = "Hello WorldWorld"; str = ReplaceFirst(str, "World", "StackOverflow "); ... string ReplaceFirst(string text, string search, string replace) { int pos = text.IndexOf(search); if (pos >= 0) { return text.Substring(0, pos) + replace + text.Substring(pos + search.Length); } return text; } 

Este ejemplo abstrae las subcadenas (pero es más lento), pero probablemente sea mucho más rápido que un RegEx:

 var parts = contents.ToString().Split(new string[] { "needle" }, 2, StringSplitOptions.None); return parts[0] + "replacement" + parts[1]; 
 string abc = "AAAAX1"; if(abc.IndexOf("AA") == 0) { abc.Remove(0, 2); abc = "XQ" + abc; }