admin 管理员组

文章数量: 1086019

I need to replace character sequences in a string, but they are not guaranteed not to be overlapping. The rule in case of conflicts is that ( first, the longest character sequence wins, but this is irrelevant), but if they are the same length the ones closest to the end must take priority. I would like to use a StringBuilder for this, but I'm not sure how to implement this.

The code below illustrates this:

string source = "abaaaababa";
var sb = new StringBuilder(source);
Console.WriteLine("What I want:" + ReplaceFromRight(source,"aba","dgd"));
Console.WriteLine("What I have:" + sb.Replace("aba", "dgd").ToString());

string ReplaceFromRight(string text, string from, string to)
{
    for (int i = text.Length-from.Length; i >=0 ; i--)
    {
        if(text.Substring(i, from.Length) == from)
            text = text.Substring(0,i)+to+text.Substring(i+from.Length);
    }
    return text;
}
What I want:dgdaaabdgd
What I have:dgdaadgdba

(ReplaceFromRight is quick and dirty, I know, but it illustrates my purpose)

What is the best way to do this?

Here's what I came up with:

string ReplaceFromRightWithSb(StringBuilder sb, string from, string to)
{
    var text = sb.ToString();
    var lastIndex=text.LastIndexOf(from);
    while (lastIndex > -1)
    {
        sb.Replace(from, to, lastIndex, from.Length);
        text = sb.ToString();
        lastIndex = text.LastIndexOf(from);
    }
    return sb.ToString();
}

(it's basically what Tim said below, so I will accept his answer)

I need to replace character sequences in a string, but they are not guaranteed not to be overlapping. The rule in case of conflicts is that ( first, the longest character sequence wins, but this is irrelevant), but if they are the same length the ones closest to the end must take priority. I would like to use a StringBuilder for this, but I'm not sure how to implement this.

The code below illustrates this:

string source = "abaaaababa";
var sb = new StringBuilder(source);
Console.WriteLine("What I want:" + ReplaceFromRight(source,"aba","dgd"));
Console.WriteLine("What I have:" + sb.Replace("aba", "dgd").ToString());

string ReplaceFromRight(string text, string from, string to)
{
    for (int i = text.Length-from.Length; i >=0 ; i--)
    {
        if(text.Substring(i, from.Length) == from)
            text = text.Substring(0,i)+to+text.Substring(i+from.Length);
    }
    return text;
}
What I want:dgdaaabdgd
What I have:dgdaadgdba

(ReplaceFromRight is quick and dirty, I know, but it illustrates my purpose)

What is the best way to do this?

Here's what I came up with:

string ReplaceFromRightWithSb(StringBuilder sb, string from, string to)
{
    var text = sb.ToString();
    var lastIndex=text.LastIndexOf(from);
    while (lastIndex > -1)
    {
        sb.Replace(from, to, lastIndex, from.Length);
        text = sb.ToString();
        lastIndex = text.LastIndexOf(from);
    }
    return sb.ToString();
}

(it's basically what Tim said below, so I will accept his answer)

Share Improve this question edited Mar 27 at 11:04 Fildor 16.2k4 gold badges43 silver badges81 bronze badges asked Mar 27 at 9:35 Vladimirs KacsVladimirs Kacs 53 bronze badges 5
  • Replace always works from the start of the String(buillder) towards the end. A simple (but not necessarly the most efficient) way for ReplaceFromRight would be reversing the original string, search term and replacement term before calling Replace and again reverse the result afterwards – derpirscher Commented Mar 27 at 9:47
  • Is it only in my browser? Cannot seem to fix code highlighting. (I edited to fix a typo) – Fildor Commented Mar 27 at 9:50
  • 1 @Fildor, no it's not your browser. For some reason code markup shows in preview but not in the question. – Vladimirs Kacs Commented Mar 27 at 9:59
  • var result = Regex.Replace("abaaaababa", "aba", "dgd", RegexOptions.RightToLeft); – Dmitrii Bychenko Commented Mar 27 at 10:01
  • If you want to provide the answer for future readers, then post the answer as the answer, don't edit it into question. – Sinatr Commented Mar 27 at 10:28
Add a comment  | 

1 Answer 1

Reset to default 0

If i understood it right, this should work: Demo

public static string ReplaceFromRight(string text, string from, string to)
{
    var sb = new StringBuilder(text);
    for (int i = text.Length - from.Length; i >= 0; i--)
    {
        if (text.Substring(i, from.Length) == from)
        {
            sb.Remove(i, from.Length);
            sb.Insert(i, to);
            text = sb.ToString();
        }
    }
    return sb.ToString();
}

本文标签: cHow to Replace with StringBuilder from the rightStack Overflow