替换字符串中单词的最后一次出现-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

现在,它已经取代两次出现的TnaNamefeb11。有什么办法可以只替换字符串中单词的最后一次出现?

注意:feb11TnaName来自另一个过程的-这不是问题。


您唯一的目标是替换路径的最后一部分吗?(也就是说,是从/开始吗?)
Simon Whitehead

没有最后一部分,最后只有TnaName路径,但我仅生成有问题的样本。谢谢。
Shree

1
该字符串是否总是通往某物的路径?考虑使用System.IO.Path类。
Yuriy Rozhovetskiy

是的,字符串始终是通往某事物的路径。
Shree

Answers:


176

这是替换字符串最后一次出现的函数

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。
Shree

6
当心,也许没有比赛(即Place == -1
Alireza Noori 2014年

7
如果找不到匹配项,则返回源比空字符串更合乎逻辑。
萨沙(Sasha)2015年

2
您应该返回“ return Source;”。而不是“ return sting.Empty;” 因为如果找不到Find字符串,则其逻辑失败。
Jignesh Variya

1
加入之间(字符串来源为:public static string ReplaceLastOccurance(this string Source...和你有漂亮的扩展方法,你可以用它来替换字符串最后出现的任何字符串。
beaudetious

12

使用string.LastIndexOf()查找的字符串中最后一次出现的索引,然后用子串来寻找解决方案。



3

我不明白为什么不能使用Regex:

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

你的意思是,return Regex.Replace(Regex.Replace(source),pattern, replacement);
toddmo '17

假设有人调用ReplaceEnd(“(foobar)”,“)”,“ thenewend”)。您的函数将抛出异常,因为“)$”是无效的正则表达式。这将起作用:返回RegexReplace(source,Regex.Escape(value)+“ $”,替换); 您的RemoveEnd也是如此。
jcox

@jcox,我想不出如何避免两次转义,因为每个函数都是公共的,所以我们有多个潜在的调用路径。就我而言,我没有将其用于特殊字符,但我确实明白你的意思。
toddmo

@toddmo我将让ReplaceEnd和RemoveEnd直接调用Regex.Replace。不过有点离题。我只是想让人们意识到,将用户输入注入到正则表达式模式可能很棘手。类似于将输入注入XML或SQL一样-需要某种转义机制。
jcox

1

您可以使用namepace中的PathSystem.IO

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

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

0

该解决方案只需一行即可实现:

 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
尽管仅代码的答案可能会回答问题,但您可以通过提供代码上下文,此代码起作用的原因以及一些文档参考以进一步阅读,来显着提高答案的质量。来自“如何回答”“简洁是可以接受的,但更充分的解释会更好。”
普拉纳夫·霍桑加迪
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.