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 |1 Answer
Reset to default 0If 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();
}
Replace
always works from the start of the String(buillder) towards the end. A simple (but not necessarly the most efficient) way forReplaceFromRight
would be reversing the original string, search term and replacement term before callingReplace
and again reverse the result afterwards – derpirscher Commented Mar 27 at 9:47var result = Regex.Replace("abaaaababa", "aba", "dgd", RegexOptions.RightToLeft);
– Dmitrii Bychenko Commented Mar 27 at 10:01