Wie ersetze ich die * erste Instanz * einer Zeichenfolge in .NET?

108

Ich möchte das erste Vorkommen in einer bestimmten Zeichenfolge ersetzen.

Wie kann ich dies in .NET erreichen?

Auf Wiedersehen StackExchange
quelle
Bitte machen Sie klare Beiträge, die die Leute verstehen können. Ich habe dieses auch für dich bearbeitet. Sie sollten zumindest hier eine Sprache angegeben haben.
GEOCHET
Natürlich wird es nie ersetzt ... es ist immer eine neue Zeichenfolge, die die ursprüngliche Zeichenfolge mit ersetztem Text enthält. Dies liegt daran, dass Zeichenfolgen unveränderlich sind.
Pablo Marambio
Ich habe die Methode String.Replace () ausprobiert. aber es ersetzt alle "AA" durch "XQ"
Thorin Oakenshield
2
Diese Frage - stackoverflow.com/questions/141045/… - enthüllt alles über das, was Sie tun müssen
stack72
1
Hinweis: Zusammenführen mit einer anderen ähnlichen Frage, bei der "AA" => "XQ" als Beispiele zum Suchen / Ersetzen verwendet wurde.
Marc Gravell

Antworten:

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

Beispiel:

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

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

BEARBEITEN : Wie @itsmatt erwähnt , gibt es auch Regex.Replace (String, String, Int32), die das gleiche tun, aber es ist wahrscheinlich teurer zur Laufzeit, da es eine voll funktionsfähige Parser verwendet , wo meine Methode macht eine Entdeckung und drei Zeichenfolge Verkettungen.

EDIT2 : Wenn dies eine häufige Aufgabe ist, möchten Sie die Methode möglicherweise zu einer Erweiterungsmethode machen:

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

Mit dem obigen Beispiel ist es jetzt möglich zu schreiben:

str = str.ReplaceFirst("brown", "quick");
VVS
quelle
2
Interessanterweise haben Sie Ihre Annahme getestet, dass der Regex-Ansatz zur Laufzeit teurer ist? Wie wäre es mit Geschwindigkeit? Vielleicht ist die Suche mit Regex schneller als mit IndexOf?
Mfloryan
Ich bevorzuge die Antwort von @BilltheLizard mit Remove () und Insert () gegenüber diesem Ansatz mit Substring (). Gibt es eine Grundlage zu sagen, dass einer besser ist als der andere?
JohnC
3
Achtung: Dies funktioniert nicht richtig, wenn Unicode Zeichen oder Ligaturen kombiniert. ReplaceFirst("oef", "œ", "i")Gibt beispielsweise fälschlicherweise "ief" anstelle von "if" zurück. Weitere Informationen finden Sie in dieser Frage .
Michael Liu
2
ReSharper warnt String.IndexOf is culture specific.. Robuster zu aktualisieren int pos = text.IndexOf(search, StringComparison.Ordinal);.
Contango
64

Wie itsmatt sagte, ist Regex.Replace eine gute Wahl, aber um seine Antwort vollständiger zu machen, werde ich sie mit einem Codebeispiel ausfüllen:

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

Der dritte Parameter, in diesem Fall auf 1 gesetzt, ist die Anzahl der Vorkommen des Regex-Musters, das Sie ab dem Beginn der Zeichenfolge in der Eingabezeichenfolge ersetzen möchten.

Ich hatte gehofft, dass dies mit einer statischen Regex- Überladung möglich ist, aber leider scheint es, dass Sie eine Regex-Instanz benötigen, um dies zu erreichen.

Wes Haggard
quelle
1
Das funktioniert wörtlich "foo", aber Sie wollen eine new Regex(Regex.Escape("foo"))bildliche "foo".
Ruffin
17

Schauen Sie sich Regex.Replace an .

itsmatt
quelle
2
Insbesondere die Regex.Replace-Methode (String, String, Int32) erledigt den Trick und ist wirklich präzise.
itsmatt
15

Unter Berücksichtigung des "nur ersten" vielleicht:

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

?

Oder allgemeiner:

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

Dann:

string output = input.ReplaceFirstInstance("AA", "XQ");
Marc Gravell
quelle
11
using System.Text.RegularExpressions;

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

wird zuerst Fin finden InputStringund durch ersetzen R.

Deenesh
quelle
2
Ich vereinfachte es zu einem result = (New Regex("F")).Replace(InputString, "R", 1)
Einzeiler
Beste Antwort hier (in Verbindung mit cjbarth)
Todd Vance
8

C # -Erweiterungsmethode, die dies tut:

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

Genießen

mortenbpost
quelle
Vielen Dank! Ich habe dies geändert, um eine "RemoveFirst" -Erweiterungsmethode zu erstellen, die ... das erste Auftreten eines Zeichens aus einer Zeichenfolge entfernt.
pbh101
4
Dies schlägt fehl, wenn oldValue nicht Teil der Zeichenfolge ist.
VVS
8

In der C # -Syntax:

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

Und weil es auch VB.NET zu berücksichtigen gibt, möchte ich Folgendes anbieten:

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
Anthony Potts
quelle
4

Angenommen, dies AAmuss nur ersetzt werden, wenn es sich ganz am Anfang der Zeichenfolge befindet:

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

Wenn Sie das erste Vorkommen von ersetzen müssen AA, unabhängig davon , ob die Zeichenfolge damit beginnt oder nicht, wählen Sie die Lösung von Marc.

Oded
quelle
3

Eine der Überladungen von Regex.Replacedauert ein intfür "Die maximale Häufigkeit, mit der der Austausch erfolgen kann". Natürlich Regex.Replacemag die Verwendung für das Ersetzen von Klartext wie ein Overkill erscheinen, aber es ist sicherlich prägnant:

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

Für alle, denen ein Verweis nichts ausmacht Microsoft.VisualBasic, gibt es die ReplaceMethode :

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

Dieses Beispiel abstrahiert die Teilzeichenfolgen (ist aber langsamer), aber wahrscheinlich viel schneller als ein RegEx:

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

quelle
-1
string abc = "AAAAX1";

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

quelle