webentwicklung-frage-antwort-db.com.de

Schnellste Möglichkeit, Leerzeichen in Zeichenfolgen zu entfernen

Ich versuche, mehrere E-Mail-Adressen innerhalb von String aus der Datenbanktabelle zu trennen, aber es werden auch Leerzeichen zurückgegeben, und ich möchte das Leerzeichen schnell entfernen. 

Der folgende Code entfernt zwar Leerzeichen, wird jedoch auch langsam, wenn ich versuche, eine große Anzahl von E-Mail-Adressen in einer Zeichenfolge wie 30000 abzurufen, und dann den Leerraum zwischen ihnen zu entfernen. Das Entfernen dieser Leerzeichen dauert mehr als vier bis fünf Minuten. 

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

Könnte mir bitte jemand sagen, wie ich den Whitespace auch bei einer großen Anzahl von E-Mail-Adressen innerhalb einer Sekunde entfernen kann?

24
Joe

Ich würde eine benutzerdefinierte Erweiterungsmethode mit StringBuilder erstellen, wie:

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();
}

Verwendungszweck:

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

oder noch schneller zu sein:

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

Bei der Hashset-Version dauert eine Zeichenfolge von 11 Millionen Zeichen weniger als 700 ms (und ich bin im Debug-Modus).

BEARBEITEN:

Vorheriger Code ist generisch und ermöglicht das Ausschließen von Zeichen. Wenn Sie jedoch nur Leerzeichen auf schnellstem Weg entfernen möchten, können Sie Folgendes verwenden:

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();
}

EDIT 2:

wie in den Kommentaren richtig angegeben, ist die korrekte Methode zum Entfernen von all der Leerzeichen die char.IsWhiteSpace-Methode:

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();
}
44
digEmAll

Angesichts der Implementierung von string.Replace ist in C++ geschrieben und Teil der CLR-Laufzeit Ich bin bereit zu wetten

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

wird die schnellste Umsetzung sein. Wenn Sie jeden Whitespace-Typ benötigen, können Sie den Hex-Wert des Unicode-Äquivalents angeben.

14
Chris S

Mit linq können Sie es einfach tun:

emailaddress = new String(emailaddress
                                     .Where(x=>x!=' ' && x!='\r' && x!='\n')
                                     .ToArray());

Ich habe es nicht mit Stringbuilder-Ansätzen verglichen, ist aber viel schneller als String-basierte Ansätze ..__ Da es nicht viele Kopien von Strings erstellt (String ist unveränderlich und führt direkt zu Speicher- und Geschwindigkeitsproblemen) es wird keinen sehr großen Speicher verwenden und die Geschwindigkeit nicht verlangsamen (außer einem zusätzlichen Durchlauf durch die Zeichenfolge).

5
Saeed Amiri
emailaddress.Replace("  ", string.empty);
4
Partha Bijjam

Sie sollten String.Trim() versuchen. Es werden alle Leerzeichen vom Anfang bis zum Ende einer Zeichenfolge abgeschnitten

Oder Sie können diese Methode aus einem verknüpften Thema ausprobieren: [link]

    public static unsafe string StripTabsAndNewlines(string s)
    {
        int len = s.Length;
        char* newChars = stackalloc char[len];
        char* currentChar = newChars;

        for (int i = 0; i < len; ++i)
        {
            char c = s[i];
            switch (c)
            {
                case '\r':
                case '\n':
                case '\t':
                    continue;
                default:
                    *currentChar++ = c;
                    break;
            }
        }
        return new string(newChars, 0, (int)(currentChar - newChars));
    }
4
Evgeny Gavrin

Es gibt viele verschiedene Wege, einige schneller als andere:

public static string StripTabsAndNewlines(this string str) {

    //string builder (fast)
    StringBuilder sb = new StringBuilder(str.Length);
    for (int i = 0; i < str.Length; i++) {
        if ( !  Char.IsWhiteSpace(s[i])) {
            sb.Append();
        }
    }
    return sb.tostring();

    //linq (faster ?)
    return new string(str.ToCharArray().Where(c => !Char.IsWhiteSpace(c)).ToArray());

    //regex (slow)
    return Regex.Replace(str, @"\s+", "")

}
2
katbyte

Bitte verwenden Sie die TrimEnd()-Methode der String-Klasse. Ein tolles Beispiel finden Sie hier hier.

2
Dun
string str = "Hi!! this is a bunch of text with spaces";

MessageBox.Show(new String(str.Where(c => c != ' ').ToArray()));
1
Senagi

Sie sollten in Erwägung ziehen, Leerzeichen in dem Datensatz innerhalb Ihrer gespeicherten Prozedur zu ersetzen oder, falls möglich, die Funktion REPLACE( ) mit der Funktion emailAddress.Where(x=>{ return x != ' ';}).ToString( ) abzufragen. 

Wie bereits erwähnt, müssten Sie die verschiedenen Ansätze profilieren. Wenn Sie Regex verwenden, sollten Sie es zumindest zu einer statischen Variablen auf Klassenebene machen:

public static Regex MultipleSpaces = new Regex(@"\s+", RegexOptions.Compiled);

REPLACE( ) hat wahrscheinlich einen Funktions-Overhead, obwohl er möglicherweise für die Inline-Optimierung durch Microsoft optimiert wurde. Die Profilerstellung gibt Ihnen die Antwort.

Die effizienteste Methode wäre, einem neuen Puffer einen Puffer zuzuweisen und Zeichen für Zeichen zu kopieren und dabei die Leerzeichen zu überspringen. C # unterstützt Zeiger, sodass Sie unsicheren Code verwenden, einen Rohpuffer zuweisen und die Zeigerarithmetik wie in C kopieren können. Dies ist so schnell, wie dies möglich ist. Die __Funktion__ in SQL wird es für Sie so behandeln.

1
Matthew Erwin
string input =Yourinputstring;
string[] strings = input.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
foreach (string value in strings)
{
   string newv= value.Trim();
   if (newv.Length > 0)
   newline += value + "\r\n";
}
0
string s = " Your Text ";

string new = s.Replace(" ", string.empty);

// Output:
// "YourText"
0
Butzke

Der schnellste und allgemeinste Weg, dies zu tun (Zeilenabschlusszeichen, Registerkarten werden ebenfalls verarbeitet). Regex-leistungsfähige Einrichtungen sind zur Lösung dieses Problems nicht wirklich erforderlich, aber Regex kann die Leistung verringern.

new string
    (stringToRemoveWhiteSpaces
       .Where
       (
         c => !char.IsWhiteSpace(c)
       )
       .ToArray<char>()
    )
0
CSharpCoder