Reputation: 3451
I need to replace several substrings in a string
Let's say:
so for example "AB gives BD"
The "naive" approach doesn't work properly:
string S="AB";
S=S.Replace("A","B");
S=S.Replace("B","D");
as it will give DD instead of BD. (first A is changed to B but then is unnecessarily changed to D)
How to deal with such cases? Does it make sense with substrings of any size to do such a separate replacements?
EDIT: I gave some not real life example where in fact it would work doing it in reverse order(first B to D, then A to B) But as others noticed I'm interested in more general solutions: for any list of char substitutions and for any list of words substitutions
With chars I suppose now a good approach is just to go through all chars in a string and build a new string making replacements when necessary.
For words I suppose it could be more difficult, what if one replaced word is a part of another word?
For example
string S="man superman woman superwoman"
and I want replace "man" to "boy" and "woman" to "girl" only as single words
Upvotes: 1
Views: 497
Reputation: 17064
Assuming there are no cycles, you need to do it the other way around. Meaning:
string S="AB";
S=S.Replace("B","D");
S=S.Replace("A","B");
This way, B switches to D, then A switches to B and you have no unwanted changes.
As Niklas B. rightfully pointed out, in case of general substrings there's a different way that probably should be taken.
I would iterate over the string, storing the indexes where any of the substrings appear. Once done, then I'll go ahead and perform the actual switching. This way you cannot "run over" changes that you made.
Upvotes: 5
Reputation: 5260
Use Regex.Replace
Like the below code, you can map the strings that you want to replace with their replacement. This is more clean and for some - more readable
IDictionary<string,string> map = new Dictionary<string,string>()
{
{"A","B"},
{"B","D"},
};
var regex = new Regex(String.Join("|",map.Keys));
var newStr = regex.Replace(str, m => map[m.Value]);
Upvotes: 0
Reputation: 117
Just change order of code lines:
string S="AB";
S=S.Replace("B","D");
S=S.Replace("A","B");
Upvotes: -1
Reputation: 2965
One simple way is to simply loop through the string yourself, and then using an if-else or switch statement to test the characters and change them accordingly.
This way characters only change once.
var testString = "Hello World";
var newString = new StringBuilder();
foreach (char c in testString)
{
switch (c)
{
case 'e':
newString.Append('l');
break;
case 'l':
newString.Append('e');
break;
default:
newString.Append(c);
break;
}
}
// testString will be "Hleeo Wored"
testString = newString.ToString();
Upvotes: 3
Reputation: 201
You could first replace "A" with a token that certainly will not occur in the source string.
For example:
S=S.Replace("A","#");
S=S.Replace("B","D");
S=S.Replace("#","B");
Upvotes: 2