.NET'te bir dizenin * ilk örneğini * nasıl değiştiririm?


108

Belirli bir dizedeki ilk geçtiği yeri değiştirmek istiyorum.

Bunu .NET'te nasıl başarabilirim?


Lütfen insanların anlayabileceği net yazılar yazın. Bunu senin için de düzenledim. En azından burada bir dil belirlemeliydiniz.
GEOCHET

Tabii ki, asla değiştirilmez ... her zaman orijinali değiştirilmiş metinle içeren yeni bir dizedir. Bunun nedeni dizenin değişmez olmasıdır.
Pablo Marambio

`String.Replace () 'yöntemini denedim. ancak tüm "AA" 'yı "XQ" ile değiştiriyor
Thorin Oakenshield

2
bu soru - stackoverflow.com/questions/141045/… - yapmanız gerekenlerle ilgili her şeyi açıklıyor
stack72

1
Not: Bulmak / değiştirmek için örnek olarak "AA" => "XQ" kullanan benzer bir soruyla birleştirme.
Marc Gravell

Yanıtlar:


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

Misal:

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

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

DÜZENLEME : @itsmatt'ın bahsettiği gibi , aynı şeyi yapabilen, ancak muhtemelen çalışma zamanında daha pahalı olan Regex.Replace (String, String, Int32) var, çünkü yöntemimin bir bulduğu ve üç dizeyi yaptığı tam özellikli bir ayrıştırıcı kullanıyor birleştirmeler.

DÜZENLEME2 : Bu yaygın bir görevse, yöntemi bir uzantı yöntemi yapmak isteyebilirsiniz:

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

Yukarıdaki örneği kullanarak artık yazmak mümkün:

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

2
İlginç, normal ifade yaklaşımının çalışma zamanında daha pahalı olduğuna dair varsayımınızı test ettiniz mi? Hız nasıl? Belki Regex kullanarak arama IndexOf kullanmaktan daha hızlıdır?
mfloryan

Substring () içeren bu yaklaşım yerine @ BilltheLizard'ın Remove () ve Insert () içeren yanıtını tercih ediyorum. Birinin diğerinden daha iyi olduğunu söylemenin herhangi bir temeli var mı?
JohnC

3
Dikkat: Bu, Unicode karakterleri veya bitişik harfler birleştirildiğinde düzgün çalışmaz. Örneğin, ReplaceFirst("oef", "œ", "i")"if" yerine hatalı olarak "ief" döndürür. Daha fazla bilgi için bu soruya bakın .
Michael Liu

2
ReSharper uyarıyor String.IndexOf is culture specific.. Güncellemek için daha sağlam int pos = text.IndexOf(search, StringComparison.Ordinal);.
Contango

64

Gibi itsmatt söyledi Regex.Replace Bir kod örneği ile bunu dolduracaktır bunun için iyi bir seçim ancak onun cevabı daha eksiksiz hale getirmektir:

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

Bu durumda 1 olarak ayarlanan üçüncü parametre, dizenin başından itibaren girdi dizesinde değiştirmek istediğiniz normal ifade kalıbının oluşum sayısıdır.

Bu statik ile yapılabilir diye umuyordum Regex.Replace aşırı ama ne yazık ki bunu gerçekleştirmek için bir Regex örneğini ihtiyaç belirir.


1
Bu kelimenin tam anlamıyla işe yarıyor "foo", ancak new Regex(Regex.Escape("foo"))mecazi için bir isteyeceksiniz "foo".
2018

17

Regex'e bir göz atın .


2
Özellikle, Regex.Replace Yöntemi (String, String, Int32) hile yapacak ve gerçekten özlü olacaktır.
itsmatt

15

"Yalnızca ilk" i hesaba katarsak, belki:

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

?

Veya daha genel olarak:

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

Sonra:

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

11
using System.Text.RegularExpressions;

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

ilk Fiçinde bulacak InputStringve ile değiştirecektir R.


2
Bunu tek result = (New Regex("F")).Replace(InputString, "R", 1)
satırlık olarak

En iyi cevap burada (cjbarth ile bağlantılı olarak)
Todd Vance

8

Bunu yapacak C # uzatma yöntemi:

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

Zevk almak


Teşekkürler! Bunu bir dizeden bir karakterin ilk oluşumunu kaldıran bir "RemoveFirst" uzantı yöntemi yapmak için değiştirdim.
pbh101

4
OldValue dizenin parçası değilse bu başarısız olur.
VVS

8

C # sözdiziminde:

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

4

Ayrıca dikkate alınması gereken VB.NET de olduğu için şunları sunmak isterim:

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

4

AAYalnızca dizenin en başındaysa değiştirilmesi gerektiğini varsayar :

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

İlk geçtiği yeri AA, dizenin onunla başlayıp başlamamasına bakmaksızın değiştirmeniz gerekirse , Marc'ın çözümüne gidin.


3

Aşırı yüklerden biri Regex.Replace, int"Değiştirmenin meydana gelebileceği maksimum sayı" için alır . Açıktır ki, Regex.Replacedüz metin değiştirme için kullanmak aşırı gelebilir, ancak kesinlikle özlüdür:

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


1

Bu örnek, alt dizeleri özetler (ancak daha yavaştır), ancak muhtemelen bir Normal İfadeden çok daha hızlıdır:

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

0

SpanYeni dize oluşumunu en aza indirmek için kullanılan güncellenmiş uzantı yöntemi

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

-1
string abc = "AAAAX1";

            if(abc.IndexOf("AA") == 0)
            {
                abc.Remove(0, 2);
                abc = "XQ" + abc;
            }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.