# Regular Expression replace specific characters

Does anyone know of a better / cleaner way to write the following:

GetSafeTagName(txtUserInput.text);

public static string GetSafeTagName(string tag)
{
tag = tag.ToUpper()
.Replace("'","")
.Replace('"','')
.Replace("&", "and")
.Replace(",",":")
.Replace(@"\","/"); //Do not allow escaped characters from user
tag = Regex.Replace(tag, @"\s+", " "); //multiple spaces with single spaces
return tag;
}


Thanks!

• wow, I didn't even know that site existed, I will ask over there thanks! – ToddBFisher Nov 9 '11 at 17:48
• Here is a SO question where the answer recommends using a StringBuilder. – user786653 Nov 9 '11 at 18:54
• I once read an article by Jesse Liberty that said the decent support structure actually slowed the code down........ – user15144 Jul 23 '12 at 15:41

You could use a regular expression and Dictionary<string, string> to do the search replace:

// This regex matches either one of the special characters, or a sequence of
// more than one whitespace characters.
Regex regex = new Regex("['\"&,\\\\]|\\s{2,}");

var map = new Dictionary<string, string> {
{ "'", ""},
{ "\"", ""},
{ "&", "and" },
{ ",", ":" },
{ "\\", "/" }
};

// If the length of the match is greater that 1, then it's a sequence
// of spaces, and we can replace it by a single space. Otherwise, we
// use the dictionary to map the character.
string output = regex.Replace(input.ToUpper(),
m => m.Value.Length > 1 ? " " : map[m.Value]);

• As elegant as it may seem, sadly this alternative is 3 times slower. – detay Mar 24 '15 at 15:21

When I had to do something similar, I used a Dictionary<string, string> to define the replacements.

And then something like this to replace:

foreach( KeyValuePair<string, string> pair in replacements)
{
str = str.Replace(pair.Key, pair.Value);
}


http://msdn.microsoft.com/en-us/library/5tbh8a42.aspx

I think your method is pretty readable and clean as it stands. However, if you want to simplify the method itself, I have a decent support structure that would do so and possibly speed it up for particularly long strings:

internal static class SafeTag
{
private static readonly List<Replacement> replacements = new List<Replacement>
{
new Replacement("'", ""),
new Replacement("\"", ""),
new Replacement("&", "and"),
new Replacement(",", ":"),
new Replacement("\\", "/")
};

private static readonly Regex spaces = new Regex("\\s+", RegexOptions.Compiled);

public static string GetSafeTagName(this string tag)
{
var parse = new StringBuilder(tag.ToUpper());
replacements.ForEach(replacement => parse = parse.Replace(replacement.Original, replacement.ToReplaceWith));
return spaces.Replace(parse.ToString(), " ");
}

private struct Replacement
{

internal Replacement(string original, string toReplaceWith)
{
this.original = original;
this.toReplaceWith = toReplaceWith;
}

internal string Original
{
get
{
return this.original;
}
}

internal string ToReplaceWith
{
get
{
return this.toReplaceWith;
}
}
}
}