文字列内の単語の最後の出現を置き換えます-C#


82

文字列内の最後に出現する単語を置き換える必要があるという問題があります。

状況:次の形式の文字列が与えられます:

string filePath ="F:/jan11/MFrame/Templates/feb11";

次に、次のTnaNameように置き換えます。

filePath = filePath.Replace(TnaName, ""); // feb11 is TnaName

これは機能しますが、が私TnaNameのと同じ場合は問題がありfolder nameます。これが発生すると、次のような文字列が表示されます。

F:/feb11/MFrame/Templates/feb11

今では両方の出現に置き換えたTnaNameとしますfeb11。文字列内の最後の単語のみを置き換える方法はありますか?

注:feb11あるTnaName別のプロセスから来ている-問題はありません。


パスの最後の部分を置き換える唯一の目標はありますか?(つまり、それ/以降?)
Simon Whitehead

最後の部分ではなく、最後の部分だけTnaNameがパスにありますが、質問用のサンプルのみを生成します。ありがとうございます。
シュリー

1
この文字列は常に何かへのパスですか?使用している場合は、System.IO.Pathクラスの使用を検討してください。
Yuriy Rozhovetskiy 2013

はい文字列は常に何かへのパスです。
シュリー

回答:


179

文字列の最後の出現を置き換える関数は次のとおりです

public static string ReplaceLastOccurrence(string Source, string Find, string Replace)
{
        int place = Source.LastIndexOf(Find);

        if(place == -1)
           return Source;

        string result = Source.Remove(place, Find.Length).Insert(place, Replace);
        return result;
}
  • Source 操作を実行する文字列です。
  • Find 置き換える文字列です。
  • Replace 置き換えたい文字列です。

ジェネリック関数をどうもありがとう。それは機能し、@ Simonにも同意します。
シュリー

6
注意してください、多分一致がない(すなわちPlace == -1
Alireza Noori 2014

7
一致するものが見つからない場合は、空の文字列よりもソースを返す方がおそらく論理的です。
サーシャ2015

2
「returnSource;」を返す必要があります。「returnsting.Empty;」の代わりに 検索文字列が見つからない場合、論理が失敗したためです。
Jignesh Variya 2016年

1
追加これを間(文字列ソースのように:public static string ReplaceLastOccurance(this string Source...あなたは、あなたが任意の文字列のための文字列の最後の発生を置き換えるために使用することができます気の利いた拡張メソッドを持っている。
beaudetious

12

string.LastIndexOf()文字列の最後の出現のインデックスを見つけるために使用し、次に部分文字列を使用してソリューションを探します。


7

手動で交換する必要があります。

int i = filePath.LastIndexOf(TnaName);
if (i >= 0)
    filePath = filePath.Substring(0, i) + filePath.Substring(i + TnaName.Length);

3

正規表現を使用できない理由がわかりません。

public static string RegexReplace(this string source, string pattern, string replacement)
{
  return Regex.Replace(source,pattern, replacement);
}

public static string ReplaceEnd(this string source, string value, string replacement)
{
  return RegexReplace(source, $"{value}$", replacement);
}

public static string RemoveEnd(this string source, string value)
{
  return ReplaceEnd(source, value, string.Empty);
}

使用法:

string filePath ="F:/feb11/MFrame/Templates/feb11";
filePath = filePath.RemoveEnd("feb11"); // F:/feb11/MFrame/Templates/
filePath = filePath.ReplaceEnd("feb11","jan11"); // F:/feb11/MFrame/Templates/jan11

1
Regex.Escape()の値が必要です。
jcox 2017年

つまり、return Regex.Replace(Regex.Replace(source),pattern, replacement);
toddmo 2017年

誰かがReplaceEnd( "(foobar)"、 ")"、 "thenewend")を呼び出したとします。「)$」は無効な正規表現であるため、関数はスローされます。これは機能します:return RegexReplace(source、Regex.Escape(value)+ "$"、replacement); あなたのRemoveEndについても同じ話です。
jcox 2017年

@jcox、二重エスケープを回避する方法がわかりませんでした。b/ c各関数はパブリックであるため、複数の潜在的な呼び出しパスがあります。私の場合、特殊文字には使用していませんでしたが、あなたの主張は理解できます。
toddmo

@toddmoReplaceEndとRemoveEndでRegex.Replaceを直接呼び出す必要があります。ちょっとオフトピックですが。ユーザー入力を正規表現パターンに挿入するのは難しい場合があることを人々に知ってもらいたいと思います。XMLまたはSQLに入力を挿入するのと同様に、何らかのエスケープメカニズムが必要です。
jcox

1

namepaceのPathクラスを使用できますSystem.IO

string filePath = "F:/jan11/MFrame/Templates/feb11";

Console.WriteLine(System.IO.Path.GetDirectoryName(filePath));

0

このソリューションは、1行でさらに簡単に実装できます。

 static string ReplaceLastOccurrence(string str, string toReplace, string replacement)
    {
        return Regex.Replace(str, $@"^(.*){toReplace}(.*?)$", $"$1{replacement}$2");
    }

これにより、正規表現のアスタリスク演算子の貪欲さを利用できます。この関数は次のように使用されます。

var s = "F:/feb11/MFrame/Templates/feb11";
var tnaName = "feb11";
var r = ReplaceLastOccurrence(s,tnaName, string.Empty);

0
var lastIndex = filePath.LastIndexOf(TnaName);

filePath = filePath.Substring(0, lastIndex);

2
コードのみの回答が質問に答える場合もありますが、コードのコンテキスト、このコードが機能する理由、およびさらに読むためのドキュメントへの参照を提供することで、回答の品質を大幅に向上させることができます。答える方法「簡潔には許容ですが、充実した説明は優れています。」
PranavHosangadi20年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.