2008-09-26 19 views
92

Chcę zastąpić pierwsze wystąpienie w danym ciągu.Jak zastąpić * pierwszą instancję * ciągu w .NET?

Jak mogę to zrobić w .NET?

+0

Proszę się jasne posty, że ludzie mogą zrozumieć. Zmieniłem to także dla ciebie. Powinieneś podać przynajmniej język. – GEOCHET

+0

Oczywiście, nigdy nie jest * zastępowany * ... zawsze jest nowym ciągiem zawierającym oryginalny z zastąpionym tekstem. Jest tak dlatego, że ciąg jest niezmienny. –

+0

Próbowałem metody 'String.Replace()'. ale zastępuje wszystkie "AA" przez "XQ" –

Odpowiedz

16

Spójrz na Regex.Replace.

+2

W szczególności metoda Regex.Replace (String, String, Int32) zrobi lewę i jest naprawdę zwięzła. – itsmatt

1

Regex.Replace, szczególnie RegEx.Replace (ciąg, ciąg, int), jest prawdopodobnie tym, czego szukasz. Ten lub String.IndexOf, który da ci indeks, a następnie możesz wyciąć i odbudować ciąg z nowym tekstem, który chcesz.

Przykład wykazanie drugi (jak pierwszy wykazano @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

, więc właśnie skopiowałeś mój przykład. Dziękuję Ci bardzo. – 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); 
} 

przykład:

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

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

EDIT: jak @itsmatt mentioned, istnieje również Regex.Replace (String, String, Int32), który może zrobić to samo, ale prawdopodobnie jest droższy w środowisku wykonawczym, ponieważ używa w pełni funkcjonalnego parser, gdzie moja metoda wykonuje jedno znalezisko i trzy ciągi konkatenacji.

EDIT2: Jeśli jest to wspólne zadanie, może chcesz, aby metodę rozszerzenia stosowanej techniki

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

W powyższym przykładzie jest to teraz możliwe, aby napisać:

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

Interesujące, czy przetestowałeś założenie, że podejście regex jest droższe w czasie wykonywania? A co z prędkością? Być może wyszukiwanie przy użyciu Regex jest szybsze niż przy użyciu IndexOf? – mfloryan

+0

Ja raczej preferuję odpowiedź @BilltheLizard obejmującą Remove() i Insert() w stosunku do tego podejścia z użyciem Substring(). Czy jest jakaś podstawa do stwierdzenia, że ​​jedna jest lepsza od drugiej? – JohnC

+2

Uwaga: To nie działa poprawnie z Unicode, łącząc znaki lub ligatury. Na przykład 'ReplaceFirst (" oef "," œ "," i ")' niepoprawnie zwraca "ief" zamiast "if". Zobacz [to pytanie] (http://stackoverflow.com/q/20480016/1127114), aby uzyskać więcej informacji. –

6

Składnia C#:

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

Metoda rozszerzenia C#, która będzie to zrobić:

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

Ciesz

+0

Dzięki!Zmodyfikowałem to, aby utworzyć metodę "RemoveFirst", która ... usuwa pierwsze wystąpienie znaku z ciągu znaków. – pbh101

+3

To się nie powiedzie, jeśli stara wartość nie jest częścią ciągu. – VVS

4

A ponieważ istnieje również VB.NET do rozważenia, chciałbym ofiarować:

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

Jak itsmatt powiedział Regex.Replace jest dobry Aby to zrobić, aby odpowiedź była bardziej kompletna, wypełnię ją próbką kodu:

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

Trzeci parametr, w tym przypadku ustawiony na 1, to liczba wystąpień wzorca regex, który ma zostać zastąpiony w ciągu wejściowym od początku ciągu.

Miałem nadzieję, że można to zrobić ze statycznym przeciążeniem Regex.Replace, ale niestety wydaje się, że potrzebujesz instancji Regex, aby to wykonać.

9
using System.Text.RegularExpressions; 

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

znajdzie pierwszy F w InputString i zastąpić go R.

+1

Uprościliśmy go do jednolinijkowego przez 'result = (New Regex (" F ")). Replace (InputString," R ", 1)' – cjbarth

+0

Najlepsza odpowiedź tutaj (w połączeniu z cjbarth) –

13

Biorąc "pierwszy tylko" pod uwagę, być może:

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

?

lub bardziej ogólnie:

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

Następnie:

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

Zakłada się, że AA musi być wymieniany tylko jeśli jest na samym początku łańcucha:

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

Jeśli musisz zastąpić pierwsze wystąpienie AA, whet jej struna zaczyna się od tego, czy nie, idź z rozwiązaniem od Marca.

-1
string abc = "AAAAX1"; 

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

Jednym z przeciążeń Regex.Replace trwa int za „maksymalną liczbę razy może nastąpić wymiana”. Oczywiście, używając Regex.Replace do zastąpienia zwykłego tekstu może wydawać się przesadą, ale to na pewno zwięzły:

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

Ten przykład abstracts precz podciągi (ale wolniej), ale to chyba dużo szybko niż regex:

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

Dla każdego, że nie ma nic przeciwko odniesienie do Microsoft.VisualBasic istnieje Replace Method:

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