Replacing bad string characters with bad characters

I just wondered what the easiest way to replace string characters that should later be replaced.

For example:

var str = "[Hello World]"; //enclose all occurences of [ and ] with brackets[] str = str.Replace("[","[[]").Replace("]","[]]"); 
  • Desired result: [[]Hello World[]]
  • Actual result: [[[]]Hello World[]]

The reason, obviously, is the second replacement of an already modified row.

So, how to replace all occurrences of "bad" characters with characters containing "bad" characters?


A quick measurement of all approaches showed that StringBuilder is the most efficient way.

190kb file (all in milliseconds)

  regexTime 40.5065 replaceTime 20.8891 stringBuilderTime 6.9776 

7MB file

  regexTime 1209.3529 replaceTime 403.3985 stringBuilderTime 175.2583 

By the way, Johnโ€™s direct StringBuilder approach was twice as fast as Seheโ€™s aggregate.

I made an extension from it:

 public static String EncloseChars(this string input, char[] charsToEnclose, String leftSide, String rightSide) { if (charsToEnclose == null || leftSide == null || rightSide == null) throw new ArgumentException("Invalid arguments for EncloseChars", charsToEnclose == null ? "charsToEnclose" : leftSide == null ? "leftSide" : "rightSide"); Array.Sort(charsToEnclose); StringBuilder sb = new StringBuilder(); foreach (char c in input) { if (Array.BinarySearch(charsToEnclose, c) > -1) sb.Append(leftSide).Append(c).Append(rightSide); else sb.Append(c); } return sb.ToString(); } "[Hello World]".EncloseChars(new char[]{'[', ']'},"[","]"); 
+8
string c # replace
source share
6 answers

Here's a very inconvenient way to do this. But this has the advantage that I am very close to reliable, but I donโ€™t use regular expression (unless you want to use regular expression).

 StringBuilder sb = new StringBuilder(); foreach (char c in str.ToCharArray()) { if (c == '[' || c == ']') { sb.Append('[' + c + ']'); } else { sb.Append(c); } } string result = sb.ToString(); 
+5
source share

What about:

 str = str.Replace("[", "$1[$2") .Replace("]", "$1]$2") .Replace("$1", "[") .Replace("$2", "]"); 
+4
source share

How about this elegant regex approach:

 Regex.Replace("[Hello World]", @"[\[\]]", "[$0]"); 

Unit test it?

 [TestMethod] public void UnitTestThat() { Assert.AreEqual(@"[[]Hello World[]]", Regex.Replace("[Hello World]", @"[\[\]]", "[$0]")); } 

Test passed


Edit @JohnMcGrant

Here is a slightly less inefficient version of your code, which, incidentally, has the same behavior as the above expression:

 string result = input.Aggregate(new StringBuilder(), (a, c) => -1 != "[]".IndexOf(c) ? a.AppendFormat("[{0}]", c) : a.Append(c)).ToString(); 
+3
source share

What about:

 char[] replacedChars = str.SelectMany(ch => (ch == '[' ? new char[] {'[', '[', ']'} : (ch == ']' ? new char[] {'[', ']', ']'} : new char[] {ch}))).ToArray(); string replaced = new string(replacedChars); 

Please note that this avoids the problem of multiple loops, but creates at least as many arrays as there are characters in the input string, so it may not be optimal in terms of performance.

+1
source share
  StringBuilder result = new StringBuilder(); foreach (Char singleCharacter in str) { result.Append(singleCharacter.Equals('[') ? "[[]" : singleCharacter.Equals(']') ? "[]]" : singleCharacter.ToString()); } str = result.ToString(); 
+1
source share

I had the same problem, so I made a helper function to do just that

  protected string ReplaceUsingDictionary(string subject, Dictionary<string,string> pairs) { StringBuilder sb = new StringBuilder(subject); sb.Replace("{", "{{").Replace("}", "}}"); int i=0; foreach (string key in pairs.Keys.ToArray()) { sb.Replace( key.Replace("{", "{{").Replace("}", "}}"), "{" + i + "}" ); i++; } return string.Format(sb.ToString(), pairs.Values.ToArray()); } // usage Dictionary<string, string> replacements = new Dictionary<string, string>(); replacements["["] = "[[]"; replacements["]"] = "[]]"; string mystr = ReplaceWithDictionary("[HelloWorld]", replacements); // returns [[]HelloWorld[]] 
0
source share

All Articles