.NETで文字列の*最初のインスタンス*を置き換えるにはどうすればよいですか?


108

与えられた文字列の最初の出現を置き換えたい。

.NETでこれを実現するにはどうすればよいですか?


わかりやすい投稿をお願いします。私もあなたのためにこれを編集しました。少なくともここで言語を指定しておく必要があります。
GEOCHET 2008

もちろん、置き換えられることはありません...常に、元の文字列と置き換えられたテキストを含む新しい文字列です。これは、文字列が不変だからです。
Pablo Marambio

`String.Replace()`メソッドを試しました。しかし、すべての「AA」が「XQ」に置き換えられます
Thorin Oakenshield 2010年

2
この質問- stackoverflow.com/questions/141045/... -あなたは何をする必要があるかについてのすべてを明らかにする
stack72

1
注:検索/置換の例として「AA」=>「XQ」を使用した別の同様の質問とマージします。
Marc Gravell

回答:


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

例:

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

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

編集:@itsmattが言及したように、Regex.Replace(String、String、Int32)もあります。これは同じことを実行できますが、私のメソッドが1つの検索と3つの文字列を実行する完全な機能のパーサーを使用しているため、実行時にコストが高くなる可能性があります。連結。

EDIT2:これが一般的なタスクである場合、メソッドを拡張メソッドにすることができます。

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

上記の例を使用すると、次のように記述できます。

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

2
興味深いことに、実行時に正規表現アプローチがより高価になるという想定をテストしましたか?スピードはどうですか?おそらく、正規表現を使用した検索は、IndexOfを使用するよりも高速ですか?
mfloryan

私は、Substring()を使用するこのアプローチよりも、Remove()およびInsert()を使用する@BilltheLizardの回答を好む。一方が他方よりも優れていると言う根拠はありますか?
JohnC 2013

3
注意:これは、Unicode結合文字または合字では正しく機能しません。たとえば、ReplaceFirst("oef", "œ", "i")「if」ではなく「ief」を誤って返します。詳細については、この質問を参照してください。
Michael Liu、

2
ReSharperは警告しString.IndexOf is culture specific.ます。に更新する方が堅牢int pos = text.IndexOf(search, StringComparison.Ordinal);です。
Contango 2015

64

以下のようitsmattは言っRegex.Replaceが彼の答えは、より完全にするためにしかし、このための良い選択である私は、コードサンプルとそれを記入します。

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

この場合は1に設定されている3番目のパラメーターは、文字列の先頭から入力文字列で置き換える正規表現パターンの出現回数です。

これが静的なRegex.Replaceオーバーロードで実行できることを望んでいましたが、残念ながら、それを実行するにはRegexインスタンスが必要であるようです。


1
それは文字通り"foo"に機能しますがnew Regex(Regex.Escape("foo"))、比喩的なものを必要とするでしょう"foo"
ruffin


15

「最初のみ」を考慮に入れて、おそらく:

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

またはより一般的には:

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

次に:

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

11
using System.Text.RegularExpressions;

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

が最初Fに見つかり、InputStringで置き換えRます。


2
私はそれをワンライナーに簡略化しましたresult = (New Regex("F")).Replace(InputString, "R", 1)
cjbarth 2015

ここでのベストアンサー(cjbarthと組み合わせて)
Todd Vance

8

これを行うC#拡張メソッド:

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

楽しい


ありがとう!文字列から最初に出現する文字を削除する "RemoveFirst"拡張メソッドを作成するようにこれを変更しました。
pbh101 2009

4
oldValueが文字列の一部でない場合、これは失敗します。
VVS 2010年

8

C#構文:

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

4

考慮すべきVB.NETもあるので、私は提供したいと思います。

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

AA文字列の先頭にある場合にのみ置き換える必要があると仮定します。

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

最初に出現するを置き換える必要がある場合はAA、文字列がそれで始まるかどうかにかかわらず、Marcのソリューションを使用してください。


3

オーバーロードの一つがRegex.Replaceかかるint「交換が発生する可能性が倍の最大数」のために。明らかに、Regex.Replaceプレーンテキストの置換に使用するのはやり過ぎに思えるかもしれませんが、それは確かに簡潔です:

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


1

この例は、部分文字列を抽象化します(ただし低速です)が、おそらくRegExよりもはるかに高速です。

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

-1
string abc = "AAAAX1";

            if(abc.IndexOf("AA") == 0)
            {
                abc.Remove(0, 2);
                abc = "XQ" + abc;
            }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.