我需要做一些梦想.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("í","ï"...
但我不认为它们对长串有效。
答案 0 :(得分:4)
理查德有一个很好的答案,但是在较长的字符串上性能可能略有下降(比直接字符串替换慢约25%,如下所示)。我感到很满意,可以进一步了解这一点。实际上StackOverflow上已有几个很好的相关答案如下所示:
Fastest way to remove chars from string
C# Stripping / converting one or more characters
CodeProject上还有一篇很好的文章,涵盖了不同的选项。
http://www.codeproject.com/KB/string/fastestcscaseinsstringrep.aspx
解释为什么理查兹提供的函数答案变得越来越慢,因为更换字符串是一次发生一个字符的事实;因此,如果您有大量非映射字符,则在将字符串重新附加在一起时会浪费额外的周期。因此,如果您想从CodePlex文章中获取几点,您最终会得到一个稍微修改过的Richards答案,如下所示:
private static readonly Char[] ReplacementChars = new[] { 'á', 'é', 'í', 'ü', 'ñ' };
private static readonly Dictionary<Char, Char> ReplacementMappings = new Dictionary<Char, Char>
{
{ 'á', '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秒。
无论哪种方式,只是想在这个问题的答案中添加一些信息。
答案 1 :(得分:2)
我为ICAO Passport做了类似的事情。这些名字必须是“音译”。基本上我有一个char到char映射的字典。
Dictionary<char, char> 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();
}
答案 2 :(得分:1)
你想要的是一种通过字符串一次并完成所有替换的方法。如果你想要效率,我不确定正则表达式是最好的方法。很可能在for循环中用于测试每个字符的case开关(对于你想要替换的所有字符)更快。我想介绍两种方法。
答案 3 :(得分:0)
最好使用char数组代替Stringbuilder。 索引器比调用Append方法更快,因为:
下面的示例大约快20%(取决于您的硬件和输入字符串)
static Dictionary<char, char> mappings;
public static string TranslateV2(string s)
{
var len = s.Length;
var array = new char[len];
char c;
for (var index = 0; index < len; index++)
{
c = s[index];
if (mappings.ContainsKey(c))
array[index] = mappings[c];
else
array[index] = c;
}
return new string(array);
}