1

I need to replace several substrings in a string

Let's say:

  • replace all A in original string to B
  • replace all B in original string to D

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

6
  • just do it in reverse, B to D first and then A to B Commented Jan 27, 2014 at 16:43
  • Do you only have single characters to replace or what would be your real case? Commented Jan 27, 2014 at 16:44
  • Loop is best, but you could replace with lowercase then toUpper() when your done Commented Jan 27, 2014 at 16:44
  • 1
    Do you only need to replace chars? (single characters?) Commented Jan 27, 2014 at 16:44
  • 1
    I assume this is a duplicate of my own, isn't it? stackoverflow.com/questions/9264262/… Commented Jan 27, 2014 at 16:45

5 Answers 5

5

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Sooo, what do you do with general strings instead of single characters? This case is trivial, but the general case isn't
@NiklasB. If there is need for general substrings, I would search for occurrences of all substrings that need to be changed and store the indexes, and once I'm done I'll go ahead and perform the switches.
That's a good way to go on about it, you should write that into your answer since OP explicitely asked for this case.
3

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();

Comments

2

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");

2 Comments

Now you just replaced all occurrences of A and # to B instead of just A.
@Harrison: "a token that certainly will not occur in the source string"
0

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]);

Comments

-1

Just change order of code lines:

string S="AB";
S=S.Replace("B","D");
S=S.Replace("A","B");

1 Comment

He is giving a simple example, this can be way more complicated than that, and your answer may be not working with more complicated string.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.