Replace text while maintaining invalid code in C #

I have a set of suggestions that I need to use to replace, for example:

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

And I have a text where you can make changes. However, I have no way to know in advance the case with the specified text. So, for example, if I have:

 A bgt abc hyi. Abc Ab df h 

I have to replace and get:

 A bgt cde nyi. Cde De h 

Or as close to this as possible, i.e. save case

EDIT: As I see a lot of confusion about this, I will try to clarify a bit:

I ask how to save capital letters after replacement, and I don’t think it went well (it’s not clear what it entails), so I’ll give a more realistic example using real words.

think of it as words, replacing the expressions with your synonyms, so to speak, so if I match:

 didn't achieve success => failled miserably 

then I get the value as input:

 As he didn't achieve success, he was fired 

i would get

 As he failled miserably, he was fired 

but if it had not been capitalized, then it would have been refuted, if success or success had been capitalized, it would have been a pity if someone had more than 1 capital letters, so it would have been like

My main features (the ones that I really want to use in cosideration)

  • only the first letter of the first word, capital letter
  • only the first letter of each word with a capital letter
  • all capital letters

If I can handle those three that are compatible already, I think - these are simpler - of course, a deeper solution would be better if aviillable

Any ideas?

+7
source share
5 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 is my modified code (it turns out, these are similar steps for @Sephallia .. code and similar variable names are lol)

Now the code 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. */ 
+3
source

You can use String.IndexOf with StringComparison.CurrentCultureIgnoreCase specified to match. At this point, a character with a character replacement will work to make a swap. Capitalization can be handled by checking Char.IsUpper for the source character, and then using Char.ToUpper or Char.ToLower in the appropriate place.

+4
source

You can skip String as an array of characters and use the Char.IsUpper (char) parameter

  • Create an empty string
  • Set the loop to scroll characters
  • Check if you need to change the character to another
    • Yes: check if the character is upper or lower case, depending on the result, put the corresponding letter in a new line.
    • No: just enter this character in a new line
  • Set the source line to a new line.

It may not be the most efficient or effective way to do something, but it is simple and it works.

On the side of the note: I'm not sure how you convert the characters, but if you say, rearranging the characters down the alphabet (when you want to convert them) by a constant amount, let's say you're offset by 3. So, a β†’ d and E β†’ G or something like that, then you can get the ASCII value from the character, add 3 (if you want to convert it), and then get the character from the ASCII value. As described here . You will need to do checks to make sure you are looping from the end of the alphabet. (or at the beginning if you are shifting to the left).

Edit # 1: (Keep Keeping Up)

Really big block of code ... Sorry! It was the best I could see to do what you asked. Hope someone can come up with a more elegant way. Please make a comment or something if you need clarification!

  // (to be clear) This is Elias' (original) code modified. static void Main(string[] args) { string input = "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 => { string[] matchSplit = match.Value.Split(' '); string[] valueSplit = value.Split(' '); // Set the number of words to the lower one. // If they're the same, it doesn't matter. int numWords = (matchSplit.Length <= valueSplit.Length) ? matchSplit.Length : valueSplit.Length; // only first letter of first word capitalized // only first letter of every word capitalized // all letters capitalized char[] result = value.ToCharArray(); ; for (int i = 0; i < numWords; i++) { if (char.IsUpper(matchSplit[i][0])) { bool allIsUpper = true; int c = 1; while (allIsUpper && c < matchSplit[i].Length) { if (!char.IsUpper(matchSplit[i][c]) && char.IsLetter(matchSplit[i][c])) { allIsUpper = false; } c++; } // if all the letters of the current word are true, allIsUpper will be true. int arrayPosition = ArrayPosition(i, valueSplit); Console.WriteLine(arrayPosition); if (allIsUpper) { for (int j = 0; j < valueSplit[i].Length; j++) { result[j + arrayPosition] = char.ToUpper(result[j + arrayPosition]); } } else { // The first letter. result[arrayPosition] = char.ToUpper(result[arrayPosition]); } } } return new string(result); }, RegexOptions.IgnoreCase); } Console.WriteLine(temp); } public static int ArrayPosition(int i, string[] valueSplit) { if (i > 0) { return valueSplit[i-1].Length + 1 + ArrayPosition(i - 1, valueSplit); } else { return 0; } return 0; } 
+2
source

Replace one char at a time and use

 if(currentChar.ToString() == currentChar.ToUpper(currentChar).ToString()) { //replace with upper case variant } 
0
source

This is pretty much what Reed said. The only trick is that I'm not sure what you should do when the Find and Replace strings have different lengths. So I choose the minimum length and use this ...

 static string ReplaceCaseInsensitive(string Text, string Find, string Replace) { char[] NewText = Text.ToCharArray(); int ReplaceLength = Math.Min(Find.Length, Replace.Length); int LastIndex = -1; while (true) { LastIndex = Text.IndexOf(Find, LastIndex + 1, StringComparison.CurrentCultureIgnoreCase); if (LastIndex == -1) { break; } else { for (int i = 0; i < ReplaceLength; i++) { if (char.IsUpper(Text[i + LastIndex])) NewText[i + LastIndex] = char.ToUpper(Replace[i]); else NewText[i + LastIndex] = char.ToLower(Replace[i]); } } } return new string(NewText); } 
0
source

All Articles