I didn't believe Bittercode as he said that LINQ would outperform regex.
So I did a little test just to be sure.
Three examples of how to do this:
Dim _invalidChars As Char() = New Char() {"j"c, "a"c, "n"c}
Dim _textToStrip As String = "The quick brown fox jumps over the lazy dog"
Private Sub btnStripInvalidCharsLINQ_Click(sender As System.Object, e As System.EventArgs) Handles btnStripInvalidCharsLINQ.Click
Dim stripped As String = String.Empty
Dim sw As Stopwatch = Stopwatch.StartNew
For i As Integer = 0 To 10000
stripped = _textToStrip.Where(Function(c As Char) Not _invalidChars.Contains(c)).ToArray
Next
sw.Stop()
lblStripInvalidCharsLINQ.Text = _stripped & " - in " & sw.Elapsed.TotalMilliseconds & " ms"
End Sub
Private Sub btnStripInvalidCharsFOR_Click(sender As System.Object, e As System.EventArgs) Handles btnStripInvalidCharsFOR.Click
Dim stripped As String = String.Empty
Dim sw As Stopwatch = Stopwatch.StartNew
stripped = _textToStrip
For i As Integer = 0 To 10000
For Each c As Char In _invalidChars
stripped = stripped.Replace(c, "")
Next
Next
sw.Stop()
lblStipInvalidcharsFor.Text = stripped & " - in " & sw.Elapsed.TotalMilliseconds & " ms"
End Sub
Private Sub btnStripInvalidCharsREGEX_Click(sender As System.Object, e As System.EventArgs) Handles btnStripInvalidCharsREGEX.Click
Dim stripped As String = String.Empty
Dim sw As Stopwatch = Stopwatch.StartNew
For i As Integer = 0 To 10000
stripped = Regex.Replace(_textToStrip, "[" & New String(_invalidChars) & "]", String.Empty)
Next
sw.Stop()
lblStripInvalidCharsRegex.Text = stripped & " - in " & sw.Elapsed.TotalMilliseconds & " ms"
End Sub
The results:

So, the for loop with string.replace outperformes all the other methods.
Because of this I would make an extension function to the string object.
Module StringExtensions
<Extension()> _
Public Function ReplaceAll(ByVal InputValue As String, ByVal chars As Char(), replaceWith As Char) As String
Dim ret As String = InputValue
For Each c As Char In chars
ret = ret.Replace(c, replaceWith)
Next
Return ret
End Function
Then you could use this function nice and readably in one line:
_textToStrip.ReplaceAll(_invalidChars, CChar(String.Empty))
EDIT (10 years later):
I once again needed this to be as fast as possible.
I wrote a real performance test this time (benchmarkdotnet).
I used net6.0.
Code available in github: https://github.com/j-dc/stackoverflow_1332454
//[SimpleJob(RuntimeMoniker.Net462, baseline: true)]
//[SimpleJob(RuntimeMoniker.Net48)]
[SimpleJob(RuntimeMoniker.Net60)]
[RPlotExporter]
public class RemoveChars {
private static readonly char[] _invalidChars = new[] { 'j', 'a', 'n' };
private static readonly string _textToStrip = "The quick brown fox jumps over the lazy dog";
private static readonly HashSet<char> _invalidHash = new(new[] { 'j', 'a', 'n' });
[Benchmark]
public string Linq() {
return new string(_textToStrip.Where(x => !_invalidChars.Contains(x)).ToArray());
}
[Benchmark]
public string ForEach() {
string ret = _textToStrip;
foreach(char c in _invalidChars) {
ret = ret.Replace(Convert.ToString(c), "");
}
return ret;
}
[Benchmark]
public string Regexer() {
return Regex.Replace(_textToStrip, $"[{new string(_invalidChars) }]", string.Empty);
}
[Benchmark]
public string Hasher() {
return new string(_textToStrip.Where(x => _invalidHash.Contains(x)).ToArray());
}
[Benchmark]
public string Splitting() {
return string.Join(string.Empty, _textToStrip.Split(_invalidChars, StringSplitOptions.RemoveEmptyEntries));
}
[Benchmark]
public string Aggregate() {
return _invalidChars.Aggregate(_textToStrip, (c1, c2) => c1.Replace(Convert.ToString(c2), ""));
}
}
}
Results:
| Method |
Mean |
Error |
StdDev |
| LinqToArray |
635.2 ns |
12.20 ns |
11.42 ns |
| ForEach |
119.0 ns |
1.58 ns |
1.40 ns |
| Regexer |
392.0 ns |
7.38 ns |
8.50 ns |
| Hasher |
402.0 ns |
6.04 ns |
5.65 ns |
| Splitting |
109.8 ns |
1.84 ns |
1.72 ns |
| Aggregate |
136.6 ns |
2.62 ns |
2.45 ns |