2008-09-26 21 views
92

Quiero reemplazar la primera aparición en una cadena dada.¿Cómo reemplazo la * primera instancia * de una cadena en .NET?

¿Cómo puedo lograr esto en .NET?

+0

favor haga mensajes claros de que la gente pueda entender. Edité este para ti también. Deberías haber especificado un idioma al menos aquí. – GEOCHET

+0

Por supuesto, nunca * reemplazado * ... siempre es una nueva cadena que contiene la original con el texto reemplazado. Esto es porque la cadena es inmutable. –

+0

intenté con el método 'String.Replace()'. pero reemplaza todo el "AA" con "XQ" –

Respuesta

16

Eche un vistazo a Regex.Replace.

+2

Específicamente, Regex.Replace Method (String, String, Int32) hará el truco y es realmente conciso. – itsmatt

1

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 la última (como se demostró por primera vez por @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; 
} 
+1

así que acabas de copiar mi ejemplo. muchas gracias. – VVS

116
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 mentioned, 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 completo analizador donde mi método hace una búsqueda y tres concatenaciones de cadenas.

Edit2: Si se trata de una tarea común, es posible que desee realizar el método un método de extensión:

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

Utilizando el ejemplo anterior que ahora es posible escribir:

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

Interesante, ¿has probado tu suposición de que el enfoque de expresiones regulares es más caro en tiempo de ejecución? ¿Qué hay de la velocidad? Quizás la búsqueda con Regex es más rápida que con IndexOf? – mfloryan

+0

Prefiero la respuesta de @BilltheLizard que implica Eliminar() e Insertar() sobre este enfoque que involucra a Substring(). ¿Hay alguna base para decir que uno es mejor que el otro? – JohnC

+2

Cuidado: Esto no funciona correctamente con Unicode combinando caracteres o ligaduras. Por ejemplo, 'ReplaceFirst (" oef "," œ "," i ")' devuelve incorrectamente "ief" en lugar de "if". Consulte [esta pregunta] (http://stackoverflow.com/q/20480016/1127114) para obtener más información. –

6

En la sintaxis de C#:

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

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

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

Disfrute

+0

¡Gracias!Modifiqué esto para hacer un método de extensión "RemoveFirst" que ... elimina la primera aparición de un carácter de una cadena. – pbh101

+3

Esto fallará si oldValue no es parte de la cadena. – VVS

4

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

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 
55

Como itsmatt dijo Regex.Replace es un buen Sin embargo, para que su respuesta sea más completa, la completaré con un ejemplo 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 una sobrecarga estática de Regex.Replace pero desafortunadamente parece que necesita una instancia de Regex para lograrlo.

9
using System.Text.RegularExpressions; 

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

encontrarán primera F en InputString y sustituirla por R.

+1

Lo simplifiqué a una línea por 'resultado = (Nueva Regex (" F ")). Reemplace (InputString," R ", 1)' – cjbarth

+0

La mejor respuesta aquí (junto con cjbarth) –

13

Tomando el "principio sólo" en cuenta, tal vez:

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

continuación:

string output = input.ReplaceFirstInstance("AA", "XQ"); 
4

asume que AA sólo necesita ser reemplazado si está en el inicio de la cadena:

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

Si necesita reemplazar la primera aparición de AA, siéntase si la cuerda comienza o no, ve con la solución de Marc.

-1
string abc = "AAAAX1"; 

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

Una de las sobrecargas de Regex.Replace toma un int para "El número máximo de veces que puede ocurrir la sustitución". Obviamente, el uso de Regex.Replace para el reemplazo de texto plano puede parecer demasiado difícil, pero ciertamente es concisa:

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

En este ejemplo se abstrae las subseries (pero es más lento), pero es probablemente mucho más rápida que una expresión regular:

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

para cualquier persona que no le importa una referencia a Microsoft.VisualBasic, no es el Replace Method:

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