用有效版本替换无效字符列表(如tr)

我需要做一些梦想的.trReplace

  str = str.trReplace("áéíüñ","aeiu&"); 

它应该改变这个字符串:

  a stríng with inválid charactérs 

至:

  a string with invalid characters 

我目前的想法是:

  str = str.Replace("á","a").Replace("é","e").Replace("í","ï"... 

和:

  sb = new StringBuilder(str) sb.Replace("á","a"). sb.Replace("é","e") sb.Replace("í","ï"... 

但我不认为它们对于长弦有效。

理查德有一个很好的答案,但是在较长的琴弦上表现可能略有下降(比直线琴弦更换慢约25%,如图所示)。 我感到很满意,可以进一步了解这一点。 实际上StackOverflow上已有几个很好的相关答案如下所示:

从字符串中删除字符的最快方法

C#剥离/转换一个或多个字符

CodeProject上还有一篇关于不同选项的好文章。

http://www.codeproject.com/KB/string/fastestcscaseinsstringrep.aspx

解释为什么Richards中提供的函数回答得越慢,字符串越长,这是因为替换是一次发生一个字符的事实; 因此,如果您有大量非映射字符,则在将字符串重新附加在一起时会浪费额外的周期。 因此,如果您想从CodePlex文章中获取一些积分,您最终会得到一个稍微修改过的Richards答案,如下所示:

 private static readonly Char[] ReplacementChars = new[] { 'á', 'é', 'í', 'ü', 'ñ' }; private static readonly Dictionary ReplacementMappings = new Dictionary { { 'á', 'a'}, { 'é', 'e'}, { 'í', 'i'}, { 'ü', 'u'}, { 'ñ', '&'} }; private static string Translate(String source) { var startIndex = 0; var currentIndex = 0; var result = new StringBuilder(source.Length); while ((currentIndex = source.IndexOfAny(ReplacementChars, startIndex)) != -1) { result.Append(source.Substring(startIndex, currentIndex - startIndex)); result.Append(ReplacementMappings[source[currentIndex]]); startIndex = currentIndex + 1; } if (startIndex == 0) return source; result.Append(source.Substring(startIndex)); return result.ToString(); } 

注意并非所有边缘情况都经过测试。

注意可以用ReplacementMappings.Keys.ToArray()替换ReplacementChars,但成本很低。

假设并非每个字符都是替换字符,那么这实际上会比straigt字符串替换稍快一些(再次大约20%)。

话虽如此,请记住在考虑性能成本时,我们实际谈论的是什么……在这种情况下……优化解决方案与原始解决方案之间的差异在1000字符串上超过100,000次迭代约为1秒。

无论哪种方式,只是想在这个问题的答案中添加一些信息。

我为ICAO Passport做了类似的事情。 这些名字必须是“音译”。 基本上我有一个char到char映射的字典。

 Dictionary mappings; static public string Translate(string s) { var t = new StringBuilder(s.Length); foreach (char c in s) { char to; if (mappings.TryGetValue(c, out to)) t.Append(to); else t.Append(c); } return t.ToString(); } 

你想要的是一种通过字符串一次并完成所有替换的方法。 如果你想要效率,我不确定正则表达式是最好的方法。 很可能在for循环中用于测试每个字符的case开关(对于你想要替换的所有字符)更快。 我会介绍这两种方法。