小编典典

从字符串中删除特殊字符的最有效方法

c#

我想从字符串中删除所有特殊字符。允许的字符是AZ(大写或小写),数字(0-9),下划线(_)或点号(。)。

我有以下内容,它可以工作,但是我怀疑(我知道!)它不是很有效:

    public static string RemoveSpecialCharacters(string str)
    {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < str.Length; i++)
        {
            if ((str[i] >= '0' && str[i] <= '9')
                || (str[i] >= 'A' && str[i] <= 'z'
                    || (str[i] == '.' || str[i] == '_')))
                {
                    sb.Append(str[i]);
                }
        }

        return sb.ToString();
    }

最有效的方法是什么?正则表达式是什么样子?与普通的字符串操作相比如何?

将要清理的字符串会很短,通常长度在10到30个字符之间。


阅读 535

收藏
2020-05-19

共1个答案

小编典典

为什么您认为您的方法效率不高?实际上,这是最有效的方法之一。

您当然应该将字符读入局部变量,或者使用枚举数来减少数组访问的次数:

public static string RemoveSpecialCharacters(this string str) {
   StringBuilder sb = new StringBuilder();
   foreach (char c in str) {
      if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '.' || c == '_') {
         sb.Append(c);
      }
   }
   return sb.ToString();
}

使这种方法高效的一件事是,它可以很好地扩展。执行时间将相对于字符串的长度。如果将它用在大字符串上没有令人讨厌的惊喜。

编辑:
我进行了一项快速的性能测试,使用24个字符串运行每个功能一百万次。结果如下:

原始功能:54.5毫秒。
我建议的更改:47.1毫秒。
设置StringBuilder容量的矿井:43.3毫秒。
正则表达式:294.4 ms。

编辑2:我在上面的代码中添加了AZ和az之间的区别。(我重新进行了性能测试,没有明显的区别。)

编辑3:
我测试了lookup + char []解决方案,它运行约13毫秒。

当然,要付出的代价是巨大查找表的初始化并将其保存在内存中。嗯,这不是很多数据,但是对于这样一个微不足道的功能来说却是很多…

private static bool[] _lookup;

static Program() {
   _lookup = new bool[65536];
   for (char c = '0'; c <= '9'; c++) _lookup[c] = true;
   for (char c = 'A'; c <= 'Z'; c++) _lookup[c] = true;
   for (char c = 'a'; c <= 'z'; c++) _lookup[c] = true;
   _lookup['.'] = true;
   _lookup['_'] = true;
}

public static string RemoveSpecialCharacters(string str) {
   char[] buffer = new char[str.Length];
   int index = 0;
   foreach (char c in str) {
      if (_lookup[c]) {
         buffer[index] = c;
         index++;
      }
   }
   return new string(buffer, 0, index);
}
2020-05-19