2008-09-26 27 views
92

Je souhaite remplacer la première occurrence d'une chaîne donnée.Comment remplacer la * première instance * d'une chaîne dans .NET?

Comment puis-je accomplir cela dans .NET?

+0

S'il vous plaît faire messages clairs que les gens peuvent comprendre. J'ai édité celui-ci pour toi aussi. Vous devriez avoir spécifié une langue au moins ici. – GEOCHET

+0

Bien sûr, il n'est jamais * remplacé * ... c'est toujours une nouvelle chaîne contenant l'original avec le texte remplacé. C'est parce que les chaînes sont immuables. –

+0

J'ai essayé la méthode 'String.Replace()'. mais il remplace tous les "AA" avec "XQ" –

Répondre

16

Jetez un oeil à Regex.Replace.

+2

Plus précisément, la méthode Regex.Replace (String, String, Int32) fera l'affaire et est vraiment concise. – itsmatt

1

Regex.Replace, en particulier Regex.Replace (string, string, int), est probablement ce que vous cherchez. Cela ou String.IndexOf qui vous donnera l'index et ensuite vous pouvez couper et reconstruire la chaîne avec le nouveau texte que vous voulez.

Un exemple illustrant cette dernière (comme première mise en évidence par @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

alors vous venez de copier mon exemple. Merci beaucoup. – 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); 
} 

Exemple:

string str = "The brown brown fox jumps over the lazy dog"; 

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

EDIT: Comme @itsmatt mentioned, il y a aussi Regex.Replace (String, String, Int32), qui peut faire la même chose, mais est probablement plus cher à l'exécution, car il utilise une fonctionnalité complète analyseur où ma méthode fait une recherche et trois concaténations de chaîne.

EDIT2: Si cela est une tâche commune, vous voudrez peut-être faire la méthode une méthode d'extension:

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

En utilisant l'exemple ci-dessus, il est maintenant possible d'écrire:

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

Intéressant, avez-vous testé votre hypothèse selon laquelle l'approche regex serait plus coûteuse à l'exécution? Et à propos de la vitesse? Peut-être que la recherche avec Regex est plus rapide qu'avec IndexOf? – mfloryan

+0

Je préfère la réponse de @BilltheLizard impliquant Remove() et Insert() sur cette approche impliquant Substring(). Y at-il une base pour dire que l'un est meilleur que l'autre? – JohnC

+2

Attention: Cela ne fonctionne pas correctement avec les caractères de combinaison Unicode ou les ligatures. Par exemple, 'ReplaceFirst (" oef "," œ "," i ")' renvoie incorrectement "ief" au lieu de "if". Voir [cette question] (http://stackoverflow.com/q/20480016/1127114) pour plus d'informations. –

6

En syntaxe C#:

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

Méthode d'extension C# fera ceci:

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

Profitez

+0

Merci!J'ai modifié ceci pour faire une méthode d'extension "RemoveFirst" qui ... supprime la première occurrence d'un caractère d'une chaîne. – pbh101

+3

Cela échouera si oldValue ne fait pas partie de la chaîne. – VVS

4

Et parce qu'il ya aussi VB.NET à considérer, je voudrais offrir:

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

Comme itsmatt dit Regex.Replace est un bon choix pour ce faire cependant sa réponse plus complète, je vais le remplir avec un exemple de code:

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

Le troisième paramètre, défini sur 1 dans ce cas, est le nombre d'occurrences du modèle d'expression régulière que vous souhaitez remplacer dans la chaîne d'entrée à partir du début de la chaîne.

J'espérais que cela pourrait être fait avec une surcharge statique Regex.Replace mais malheureusement, il semble que vous ayez besoin d'une instance de Regex pour l'accomplir.

9
using System.Text.RegularExpressions; 

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

trouvera d'abord dans FInputString et le remplacer par R.

+1

Je l'ai simplifié en un seul par 'result = (New Regex (" F ").) Replace (InputString," R ", 1)' – cjbarth

+0

Meilleure réponse ici (en conjonction avec cjbarth) –

13

Prendre la "première que" compte, peut-être:

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

?

Ou plus généralement:

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

Puis:

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

Suppose que AA ne doit être remplacée si elle est au début de la chaîne:

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

Si vous devez remplacer la première occurrence de AA, aiguiser elle la chaîne commence avec ou pas, aller avec la solution de Marc.

-1
string abc = "AAAAX1"; 

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

L'une des surcharges de Regex.Replace prend un int pour « Le nombre maximum de fois que le remplacement peut se produire ». De toute évidence, à l'aide Regex.Replace pour le remplacement de texte brut peut sembler exagéré, mais il est certainement concis:

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

Cet exemple fait abstraction des sous-chaînes (mais est plus lent), mais elle est probablement beaucoup plus rapide qu'un RegEx:

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

pour tous ceux qui ne me dérange pas une référence à Microsoft.VisualBasic, il est le Replace Method:

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