.NET Fiddle

CSharp · Console

/Program.cs

using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Linq;
using System.Diagnostics;
					
public class Program
{
	private static char[] _invalidCharacters; 

	public static void Main()
	{
		var iteration = 100000;
		var paths = new List<string>()
		{
			"StringHelper.RemoveInvalidCharacters",
			"StringHelper.RemoveInvalidCharacters(\"Ok?\", 'x'));",
			"return FetchAndCache<T>(key, retrieveData, absoluteExpiry, relativeExpiry);",
			"",
			null
		};

		// Warmup
		paths.ForEach(p => RemoveInvalidCharacters(p));
		paths.ForEach(p => RemoveInvalidCharacters2(p));
		paths.ForEach(p => RemoveInvalidCharacters3(p));
		paths.ForEach(p => RemoveInvalidCharacters4(p));
		paths.ForEach(p => RemoveInvalidCharacters5(p));

		// Method 1
		var sw1 = Stopwatch.StartNew();
		for (int i = 0; i < iteration; i++)
			paths.ForEach(p => RemoveInvalidCharacters(p));
		sw1.Stop();
		Console.WriteLine(string.Format("StringHelper.RemoveInvalidCharacters 1: {0} ms", sw1.ElapsedMilliseconds));


		// Method 2
		var sw2 = Stopwatch.StartNew();
		for (int i = 0; i < iteration; i++)
			paths.ForEach(p => RemoveInvalidCharacters2(p));
		sw2.Stop();
		Console.WriteLine(string.Format("StringHelper.RemoveInvalidCharacters 2: {0} ms", sw2.ElapsedMilliseconds));


		// Method 3
		var sw3 = Stopwatch.StartNew();
		for (int i = 0; i < iteration; i++)
			paths.ForEach(p => RemoveInvalidCharacters3(p));
		sw3.Stop();
		Console.WriteLine(string.Format("StringHelper.RemoveInvalidCharacters 3: {0} ms", sw3.ElapsedMilliseconds));


		// Method 4
		var sw4 = Stopwatch.StartNew();
		for (int i = 0; i < iteration; i++)
			paths.ForEach(p => RemoveInvalidCharacters4(p));
		sw4.Stop();
		Console.WriteLine(string.Format("StringHelper.RemoveInvalidCharacters 4: {0} ms", sw4.ElapsedMilliseconds));


		// Method 5
		var sw5 = Stopwatch.StartNew();
		for (int i = 0; i < iteration; i++)
			paths.ForEach(p => RemoveInvalidCharacters5(p));
		sw5.Stop();
		Console.WriteLine(string.Format("StringHelper.RemoveInvalidCharacters 5: {0} ms", sw5.ElapsedMilliseconds));
	}

	/// <summary>
	/// List of invalid characters
	/// </summary>
	public static char[] InvalidCharacters
	{
		get
		{
			if (_invalidCharacters == null)
				_invalidCharacters = getInvalidCharacters();
			return _invalidCharacters;
		}
	}

	/// <summary>
	/// Remove all characters not accepted in a path or a filename
	/// </summary>
	/// <param name="content">String to check</param>
	/// <param name="replace">Character used to replace invalid characters</param>
	/// <param name="allowBackslashes">Do not replace backslashes</param>
	/// <returns>The content with all invalid characters replaced</returns>
	public static string RemoveInvalidCharacters2(string content, char replace = '_', bool doNotReplaceBackslashes = false)
	{
		char c;
		StringBuilder sb = new StringBuilder(content);
		for (int i = 0; i < InvalidCharacters.Length; i++)
		{
			c = InvalidCharacters[i];
			if (c != '\\' || !doNotReplaceBackslashes)
				sb.Replace(c, replace);
		}
		return sb.ToString();
	}

	public static string RemoveInvalidCharacters(string content, char replace = '_', bool doNotReplaceBackslashes = false)
	{
		if (string.IsNullOrEmpty(content))
			return content;

		var idx = content.IndexOfAny(InvalidCharacters);
		if (idx >= 0)
		{
			var sb = new StringBuilder(content);
			while (idx >= 0)
			{
				if (sb[idx] != '\\' || !doNotReplaceBackslashes)
					sb[idx] = replace;
				idx = content.IndexOfAny(InvalidCharacters, idx+1);
			}
			return sb.ToString();
		}
		return content;
	}

	public static string RemoveInvalidCharacters3(string content, char replace = '_', bool doNotReplaceBackslashes = false)
	{
		if (string.IsNullOrEmpty(content))
			return content;

		var sep = replace.ToString();
		return string.Join(sep, content.Split(InvalidCharacters));
	}

	public static string RemoveInvalidCharacters4(string content, char replace = '_', bool doNotReplaceBackslashes = false)
	{
		if (string.IsNullOrEmpty(content))
			return content;

		var sep = replace.ToString();
		return Path.GetInvalidFileNameChars().Aggregate(content, (current, c) => current.Replace(c.ToString(), sep));
	}


	public static string RemoveInvalidCharacters5(string content, char replace = '_', bool doNotReplaceBackslashes = false)
	{
		if (string.IsNullOrEmpty(content))
			return content;

		string regexSearch = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars());
		Regex r = new Regex(string.Format("[{0}]", Regex.Escape(regexSearch)));
		return r.Replace(content, replace.ToString());
	}


	private static char[] getInvalidCharacters()
	{
		var invalidChars = new List<char>();
		invalidChars.AddRange(Path.GetInvalidFileNameChars());
		invalidChars.AddRange(Path.GetInvalidPathChars());
		return invalidChars.ToArray();
	} 
}
;