Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace text while keeping case intact in C#

I have a set of sentences i need to use to do a replace, for example:

abc => cde
ab df => de
...

And i have a text where to make the changes. However i have no way to know beforehand case of said text. So, for example, if i have:

A bgt abc hyi. Abc Ab df h

I must replace and get:

A bgt cde nyi. Cde De h

Or as close to that as possible, i.e. keep case

EDIT: As i am seeing to much confusion about this i will try to clarify a bit:

I am asking about a way to keep caps after replacing and i don't think that passed through well (not well explained what thaat entails) so i will give a more realistic example using real words.

think of it like a gossary, replacing expressions by their sinonyms so to speak, so if i map:

didn't achieve success => failled miserably

then the i get as input the setence:

As he didn't achieve success, he was fired

i would get

As he failled miserably, he was fired

but if didn't was capitalized, so would failled, if achieve or success was capitalized, so would miserably, if any had more than 1 letter capitalized, so would it's counterpart

My main possibilities are (ones i really want to take into cosideration)

  • only first letter of first word capitalized
  • only first letter of every word capitalized
  • all letters capitalized

If i can handle those three that would be acceaptable already i guess - it's the easyer ones - of course a more in depth solution would be better if availlable

Any ideas?

like image 987
537mfb Avatar asked Jun 19 '12 15:06

537mfb


1 Answers

Not sure how well this will work, but this is what I came up with:

        string input = "A bgt abc hyi. Abc Ab df h";
        Dictionary<string, string> map = new Dictionary<string, string>();
        map.Add("abc", "cde");
        map.Add("ab df", "de");

        string temp = input;
        foreach (var entry in map)
        {
            string key = entry.Key;
            string value = entry.Value;
            temp = Regex.Replace(temp, key, match =>
            {
                bool isUpper = char.IsUpper(match.Value[0]);

                char[] result = value.ToCharArray();
                result[0] = isUpper
                    ? char.ToUpper(result[0])
                    : char.ToLower(result[0]);
                return new string(result);
            }, RegexOptions.IgnoreCase);
        }
        label1.Text = temp; // output is A bgt cde hyi. Cde De h

EDIT After reading the modified question, here's my modified code (it turns out to be similar steps to @Sephallia's code.. and similar variable names lol )

The code now is a bit more complicated.. but I think it's ok

        string input = 
        @"As he didn't achieve success, he was fired.
        As he DIDN'T ACHIEVE SUCCESS, he was fired.
        As he Didn't Achieve Success, he was fired.
        As he Didn't achieve success, he was fired.";
        Dictionary<string, string> map = new Dictionary<string, string>();
        map.Add("didn't achieve success", "failed miserably");


        string temp = input;
        foreach (var entry in map)
        {
            string key = entry.Key;
            string value = entry.Value;
            temp = Regex.Replace(temp, key, match =>
            {
                bool isFirstUpper, isEachUpper, isAllUpper;

                string sentence = match.Value;
                char[] sentenceArray = sentence.ToCharArray();

                string[] words = sentence.Split(' ');

                isFirstUpper = char.IsUpper(sentenceArray[0]);

                isEachUpper = words.All(w => char.IsUpper(w[0]) || !char.IsLetter(w[0]));

                isAllUpper = sentenceArray.All(c => char.IsUpper(c) || !char.IsLetter(c));

                if (isAllUpper)
                    return value.ToUpper();

                if (isEachUpper)
                {
                    // capitalize first of each word... use regex again :P
                    string capitalized = Regex.Replace(value, @"\b\w", charMatch => charMatch.Value.ToUpper());
                    return capitalized;
                }


                char[] result = value.ToCharArray();
                result[0] = isFirstUpper
                    ? char.ToUpper(result[0])
                    : char.ToLower(result[0]);
                return new string(result);
            }, RegexOptions.IgnoreCase);
        }
        textBox1.Text = temp; 
        /* output is :
        As he failed miserably, he was fired.
        As he FAILED MISERABLY, he was fired.
        As he Failed Miserably, he was fired.
        As he Failed miserably, he was fired.
        */
like image 165
Elias Avatar answered Oct 07 '22 16:10

Elias