Quero substituir a primeira ocorrência em uma determinada string.
Como posso fazer isso no .NET?
Quero substituir a primeira ocorrência em uma determinada string.
Como posso fazer isso no .NET?
Respostas:
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);
}
Exemplo:
string str = "The brown brown fox jumps over the lazy dog";
str = ReplaceFirst(str, "brown", "quick");
EDIT : Como @itsmatt mencionou , há também Regex.Replace (String, String, Int32), que pode fazer o mesmo, mas provavelmente é mais caro em tempo de execução, já que está utilizando um analisador completo onde meu método faz um find e três strings concatenações.
EDIT2 : Se esta é uma tarefa comum, você pode querer tornar o método um método de extensão:
public static class StringExtension
{
public static string ReplaceFirst(this string text, string search, string replace)
{
// ...same as above...
}
}
Usando o exemplo acima, agora é possível escrever:
str = str.ReplaceFirst("brown", "quick");
ReplaceFirst("oef", "œ", "i")
retorna incorretamente "ief" em vez de "if". Veja esta pergunta para mais informações.
String.IndexOf is culture specific.
. Mais robusto para atualizar int pos = text.IndexOf(search, StringComparison.Ordinal);
.
Como itsmatt disse, Regex.Replace é uma boa escolha para isso, porém, para tornar sua resposta mais completa, vou preenchê-la com um exemplo 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"
O terceiro parâmetro, definido como 1 neste caso, é o número de ocorrências do padrão regex que você deseja substituir na string de entrada desde o início da string.
Eu esperava que isso pudesse ser feito com uma sobrecarga estática de Regex.Replace, mas, infelizmente, parece que você precisa de uma instância de Regex para fazer isso.
"foo"
, mas você vai querer um new Regex(Regex.Escape("foo"))
para o figurativo "foo"
.
Dê uma olhada em Regex.Replace .
Levando o "primeiro apenas" em consideração, talvez:
int index = input.IndexOf("AA");
if (index >= 0) output = input.Substring(0, index) + "XQ" +
input.Substring(index + 2);
?
Ou mais geralmente:
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);
}
Então:
string output = input.ReplaceFirstInstance("AA", "XQ");
using System.Text.RegularExpressions;
RegEx MyRegEx = new RegEx("F");
string result = MyRegex.Replace(InputString, "R", 1);
irá encontrar primeiro F
em InputString
e substituí-lo por R
.
result = (New Regex("F")).Replace(InputString, "R", 1)
Método de extensão C # que fará isso:
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);
}
}
Aproveitar
Na sintaxe C #:
int loc = original.IndexOf(oldValue);
if( loc < 0 ) {
return original;
}
return original.Remove(loc, oldValue.Length).Insert(loc, newValue);
E porque também há VB.NET a considerar, eu gostaria de oferecer:
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
Uma das sobrecargas de Regex.Replace
leva um int
para "O número máximo de vezes que a substituição pode ocorrer". Obviamente, usar Regex.Replace
para substituição de texto simples pode parecer um exagero, mas certamente é conciso:
string output = (new Regex("AA")).Replace(input, "XQ", 1);
Para quem não se importa com uma referência Microsoft.VisualBasic
, existe o Replace
Método :
string result = Microsoft.VisualBasic.Strings.Replace("111", "1", "0", 2, 1); // "101"
Este exemplo abstrai as substrings (mas é mais lento), mas provavelmente é muito mais rápido do que um 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;
}