删除字符串中空白区域的最快方法

Joe*_*Joe 24 .net c# string whitespace

我正在尝试从数据库表中的字符串中获取由","分隔的多个电子邮件地址,但它也返回了我的空格,我想快速删除空白.

下面的代码并删除空白,但每当我尝试像30000的字符串来获取大量的电子邮件地址,它也变得缓慢,然后尝试消除它们之间的空白.删除这些空间需要四到五分钟.

 Regex Spaces =
        new Regex(@"\s+", RegexOptions.Compiled);
txtEmailID.Text = MultipleSpaces.Replace(emailaddress),"");
Run Code Online (Sandbox Code Playgroud)

任何人都可以告诉我,即使是大量的电子邮件地址,如何在一秒内删除空格?

dig*_*All 44

我会使用StringBuilder如下构建自定义扩展方法:

public static string ExceptChars(this string str, IEnumerable<char> toExclude)
{
    StringBuilder sb = new StringBuilder(str.Length);
    for (int i = 0; i < str.Length; i++)
    {
        char c = str[i];
        if (!toExclude.Contains(c))
            sb.Append(c);
    }
    return sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)

用法:

var str = s.ExceptChars(new[] { ' ', '\t', '\n', '\r' });
Run Code Online (Sandbox Code Playgroud)

或者更快:

var str = s.ExceptChars(new HashSet<char>(new[] { ' ', '\t', '\n', '\r' }));
Run Code Online (Sandbox Code Playgroud)

使用hashset版本,一个包含11百万个字符的字符串不到700毫秒(我正处于调试模式)

编辑:

以前的代码是通用的,允许排除任何char,但如果你想以最快的方式删除空白,你可以使用:

public static string ExceptBlanks(this string str)
{
    StringBuilder sb = new StringBuilder(str.Length);
    for (int i = 0; i < str.Length; i++)
    {
        char c = str[i];
        switch (c)
        {
            case '\r':
            case '\n':
            case '\t':
            case ' ':
                continue;
            default:
                sb.Append(c);
                break;
        }
    }
    return sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)

编辑2:

正如在评论中正确指出的,删除所有空格的正确方法是使用char.IsWhiteSpace方法:

public static string ExceptBlanks(this string str)
{
    StringBuilder sb = new StringBuilder(str.Length);
    for (int i = 0; i < str.Length; i++)
    {
        char c = str[i];
        if(!char.IsWhiteSpace(c))
            sb.Append(c);
    }
    return sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)

  • 更好的是使用`StringBuilder sb = new StringBuilder(str.Length);` (3认同)
  • 你可以为这个解决方案创建lightspeed哈希:`byte [] hash = new byte [255];`如果要排除`\ t`你做`b [(int)'\ t'] = 1`然后检查一样的方法.但它只适用于ascii :) (2认同)

Chr*_*s S 14

鉴于string.Replace用C++编写的实现和部分CLR运行时我愿意打赌

email.Replace(" ","").Replace("\t","").Replace("\n","").Replace("\r","");

将是最快的实施.如果你需要每种类型的空格,你可以提供unicode等效的十六进制值.

  • 是的,这真的很快,但这会创建4个字符串而不是1.这在长字符串的情况下会慢一点,使用StringBuilder的自定义实现比这更快. (2认同)
  • 据我所知,这是一个单独的字符串,其中有很多电子邮件以逗号分隔......但说实话,我不确定...... (2认同)

Sae*_*iri 5

使用linq你可以简单地做到:

emailaddress = new String(emailaddress
                                     .Where(x=>x!=' ' && x!='\r' && x!='\n')
                                     .ToArray());
Run Code Online (Sandbox Code Playgroud)

我没有将它与stringbuilder方法进行比较,但比基于字符串的方法快得多.因为它不会创建许多字符串副本(字符串是不可变的并且直接使用它会导致显着的内存和速度问题),所以它不会使用非常大的内存而不会减慢速度(除了一个额外的通过首先是字符串).

  • 我真的怀疑这是否“快” (2认同)