# Replacing from a list chars in a string

Often I need to clean a file name using Path.GetInvalidFileNameChars(), however I do not know of a way to search for any of the invalid letters (except by using Regex) in one pass.

public string LoopMethod()
{
StringBuilder sb = new StringBuilder(fileName);
foreach(var invalidChar in Path.GetInvalidFileNameChars())
{
sb.Replace(invalidChar, '_');
}
return sb.ToString();
}

Regex invalidCharsRegex;
public void RegexMethodInit()
{
var invalidChars = Path.GetInvalidPathChars().Select(c => Regex.Escape(c.ToString())).ToString();
invalidCharsRegex = new Regex(string.Join("|", invalidChars));
}

public string RegexMethod(string fileName)
{
return invalidCharsRegex.Replace(fileName, "_");
}


Is one of those ways the "correct" way to to this or is there a better function I am missing?

-
Related: forums.asp.net/t/1185961.aspx/1 –  Rice Flour Cookies Feb 21 '13 at 23:28
@Leonid Path.GetInvalidPathChars() returns a char[] of characters that are illegal in a file name. What I wanted to know is what is the proper way to clean a filename from the returned char[], is it to just loop like in my example, or is there a function that can take in a char[] and replace on a string in one operation? –  Scott Chamberlain Feb 22 '13 at 0:11

foreach(var c in Path.GetInvalidPathChars())
path = path.replace(c, '_')


That's a bit inefficient as it can allocate a string on every itteration, but usually not a problem. Alternative:

var chars = Path.GetInvalidPathChars()
path = new string(path.Select(c => chars.Contains(c) ? '_' : c).ToArray())

-
Ah, your answer is better, except that you are not using a set. Using a set may speed things up or slow them down depending on the size of the array. Either way this function should run fast. –  Leonid Feb 23 '13 at 0:15
Come to think of it, this code is doing File IO, any of these solutions is fine. They'll all be several levels of magnitude faster than doing File IO. –  Robert Wagner Feb 23 '13 at 10:50

You can just make a regex of the "[abcdef]" type; it'll match all characters inside the brackets. No need to join them with |.

I use this function, which uses the above regex type, and utilizes the fact you can simply make a string from a character array. Since it was written for converting a document title to a file name it uses spaces as replace characters, and somewhat trims the final result by collapsing any double spaces.

public static String MakeSafeFileName(String input)
{
// make regex of illegal characters list
String illegalChars = "["+ Regex.Escape(new String(Path.GetInvalidFileNameChars())) + "]";
// replace characters by space
input = Regex.Replace(input, illegalChars, " ");
// replace double spaces by a single space
input = Regex.Replace(input, "\\s\\s+", " ");
return input;
}

-