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 F
w InputString
i 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 AA
należ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 Replace
metoda :
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 Span
do 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;
}