Chcę zamienić pierwsze wystąpienie w danym ciągu.
Jak mogę to osiągnąć w .NET?
Chcę zamienić pierwsze wystąpienie w danym ciągu.
Jak mogę to osiągnąć w .NET?
Odpowiedzi:
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");
EDYCJA : Jak wspomniano @itsmatt , istnieje również Regex.Replace (String, String, Int32), który może zrobić to samo, ale prawdopodobnie jest droższy w czasie wykonywania, ponieważ wykorzystuje w pełni funkcjonalny parser, w którym moja metoda wykonuje jedno wyszukiwanie i trzy ciągi konkatenacje.
EDIT2 : Jeśli jest to typowe zadanie, możesz chcieć uczynić tę metodę metodą rozszerzającą:
public static class StringExtension
{
public static string ReplaceFirst(this string text, string search, string replace)
{
// ...same as above...
}
}
Korzystając z powyższego przykładu można teraz napisać:
str = str.ReplaceFirst("brown", "quick");
ReplaceFirst("oef", "œ", "i")niepoprawnie zwraca „ief” zamiast „if”. Zobacz to pytanie, aby uzyskać więcej informacji.
String.IndexOf is culture specific.. Bardziej niezawodny do aktualizacji int pos = text.IndexOf(search, StringComparison.Ordinal);.
Jak powiedział itsmatt , Regex.Replace to dobry wybór, jednak aby jego odpowiedź była bardziej kompletna, uzupełnię ją przykładowym kodem:
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 wyrażenia regularnego, który chcesz zamienić w ciągu wejściowym od początku ciągu.
Miałem nadzieję, że można to zrobić za pomocą statycznego przeciążenia Regex.Replace, ale niestety wygląda na to, że potrzebujesz instancji Regex, aby to osiągnąć.
"foo", ale będziesz potrzebować new Regex(Regex.Escape("foo"))przenośnego "foo".
Spójrz na Regex.Replace .
Biorąc pod uwagę „tylko pierwszy”, 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");
using System.Text.RegularExpressions;
RegEx MyRegEx = new RegEx("F");
string result = MyRegex.Replace(InputString, "R", 1);
znajdzie pierwszy Fw InputStringi zastąpi go R.
result = (New Regex("F")).Replace(InputString, "R", 1)
Metoda rozszerzenia C #, która zrobi to:
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);
}
}
Cieszyć się
W składni C #:
int loc = original.IndexOf(oldValue);
if( loc < 0 ) {
return original;
}
return original.Remove(loc, oldValue.Length).Insert(loc, newValue);
A ponieważ do rozważenia jest również VB.NET, chciałbym zaoferować:
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
Zakłada, że AAnależy wymienić tylko wtedy, gdy znajduje się na samym początku ciągu:
var newString;
if(myString.StartsWith("AA"))
{
newString ="XQ" + myString.Substring(2);
}
Jeśli chcesz zamienić pierwsze wystąpienie AA, niezależnie od tego, czy ciąg zaczyna się od niego, czy nie, skorzystaj z rozwiązania od Marca.
Dla każdego, komu nie przeszkadza odniesienie Microsoft.VisualBasic, istnieje Replacemetoda :
string result = Microsoft.VisualBasic.Strings.Replace("111", "1", "0", 2, 1); // "101"
Ten przykład usuwa podciągi (ale jest wolniejszy), ale prawdopodobnie jest znacznie szybszy niż wyrażenie regularne:
var parts = contents.ToString().Split(new string[] { "needle" }, 2, StringSplitOptions.None);
return parts[0] + "replacement" + parts[1];
Zaktualizowana metoda rozszerzenia wykorzystująca Spando zminimalizowania tworzenia nowych ciągów
public static string ReplaceFirstOccurrence(this string source, string search, string replace) {
int index = source.IndexOf(search);
if (index < 0) return source;
var sourceSpan = source.AsSpan();
return string.Concat(sourceSpan.Slice(0, index), replace, sourceSpan.Slice(index + search.Length));
}
string abc = "AAAAX1";
if(abc.IndexOf("AA") == 0)
{
abc.Remove(0, 2);
abc = "XQ" + abc;
}