Angenommen, ich habe eine Zeichenfolge wie:
"Hello how are you doing?"
Ich möchte eine Funktion, die mehrere Räume in einen Raum verwandelt.
Also würde ich bekommen:
"Hello how are you doing?"
Ich weiß, ich könnte Regex verwenden oder anrufen
string s = "Hello how are you doing?".replace(" "," ");
Aber ich müsste es mehrmals aufrufen, um sicherzustellen, dass alle sequentiellen Leerzeichen durch nur eines ersetzt werden.
Gibt es dafür bereits eine eingebaute Methode?
c#
string
whitespace
Matt
quelle
quelle
Antworten:
quelle
Diese Frage ist nicht so einfach, wie andere Poster es sich vorgestellt haben (und wie ich ursprünglich geglaubt habe) - weil die Frage nicht ganz so präzise ist, wie sie sein muss.
Es gibt einen Unterschied zwischen "Leerzeichen" und "Leerzeichen". Wenn Sie nur Leerzeichen meinen, sollten Sie einen regulären Ausdruck von verwenden
" {2,}"
. Wenn Sie meinen , alle Leerzeichen, das ist eine andere Sache. Sollten alle Leerzeichen in Leerzeichen umgewandelt werden? Was soll am Anfang und am Ende mit dem Weltraum passieren?Für den unten stehenden Benchmark habe ich angenommen, dass Sie sich nur um Leerzeichen kümmern und auch am Anfang und am Ende nichts mit einzelnen Leerzeichen tun möchten.
Beachten Sie, dass Korrektheit fast immer wichtiger ist als Leistung. Die Tatsache, dass die Split / Join-Lösung alle führenden / nachfolgenden Leerzeichen (auch nur einzelne Leerzeichen) entfernt, ist in Bezug auf Ihre angegebenen Anforderungen falsch (was natürlich unvollständig sein kann).
Der Benchmark verwendet MiniBench .
Einige Testläufe:
Hier ist die erste Zahl die Anzahl der Iterationen, die zweite die benötigte Zeit und die dritte eine skalierte Punktzahl, wobei 1,0 die beste ist.
Dies zeigt, dass zumindest in einigen Fällen (einschließlich diesem) ein regulärer Ausdruck die Split / Join-Lösung manchmal mit einem sehr signifikanten Vorsprung übertreffen kann .
Wenn Sie jedoch zu einer Anforderung "Alle Leerzeichen" wechseln, scheint Split / Join zu gewinnen. Wie so oft steckt der Teufel im Detail ...
quelle
Ein reguläres Expressoin wäre der einfachste Weg. Wenn Sie die Regex richtig schreiben, benötigen Sie nicht mehrere Anrufe.
Ändern Sie es in dieses:
quelle
@"\s{2,}"
ist, dass einzelne Registerkarten und andere Unicode-Leerzeichen nicht durch Leerzeichen ersetzt werden können. Wenn Sie 2 Registerkarten durch ein Leerzeichen ersetzen möchten, sollten Sie wahrscheinlich 1 Registerkarte durch ein Leerzeichen ersetzen.@"\s+"
werde das für dich tun.Obwohl die vorhandenen Antworten in Ordnung sind, möchte ich auf einen Ansatz hinweisen, der nicht funktioniert:
Dies kann für immer wiederholt werden. Möchte jemand raten warum? (Ich bin erst darauf gestoßen, als es vor ein paar Jahren als Newsgroup-Frage gestellt wurde ... jemand ist tatsächlich als Problem darauf gestoßen.)
quelle
Wie bereits erwähnt, kann dies leicht durch einen regulären Ausdruck erreicht werden. Ich füge nur hinzu, dass Sie möglicherweise eine .trim () hinzufügen möchten, um führende / nachfolgende Leerzeichen zu entfernen.
quelle
Hier ist die Lösung, mit der ich arbeite. Ohne RegEx und String.Split.
also kannst du:
quelle
Ein schneller zusätzlicher Whitespace-Entferner ... Dies ist der schnellste und basiert auf Felipe Machados In-Place-Kopie.
Die Benchmarks ...
InPlaceCharArraySpaceOnly von Felipe Machado auf CodeProject 2015 und modifiziert von Sunsetquest für das Entfernen mehrerer Leerzeichen. Zeit: 3,75 Zecken
InPlaceCharArray von Felipe Machado 2015 und leicht modifiziert von Sunsetquest zum Entfernen mehrerer Räume. Zeit 6.50 Ticks (unterstützt auch Tabs)
SplitAndJoinOnSpace von Jon Skeet . Zeit: 13,25 Zecken
StringBuilder von fubo Zeit: 13,5 Ticks (unterstützt auch Tabs)
Regex mit Kompilierung von Jon Skeet . Zeit: 17 Zecken
StringBuilder von David S 2013 Zeit: 30,5 Ticks
Regex mit Nichtkompilierung von Brandon Zeit: 63,25 Ticks
StringBuilder von user214147 Zeit: 77.125 Ticks
Regex mit nicht kompiliertem Tim Hoolihan Zeit: 147,25 Ticks
Der Benchmark-Code ...
}}
Benchmark-Hinweise: Release-Modus, kein Debugger angeschlossen, i7-Prozessor, durchschnittlich 4 Läufe, nur kurze getestete Zeichenfolgen
quelle
Ich teile, was ich benutze, weil ich anscheinend etwas anderes gefunden habe. Ich benutze das schon eine Weile und es ist schnell genug für mich. Ich bin mir nicht sicher, wie es sich gegen die anderen schlägt. Ich verwende es in einem begrenzten Dateischreiber und führe große Datentabellen feldweise durch.
quelle
Mit dem von Jon Skeet veröffentlichten Testprogramm habe ich versucht zu prüfen, ob eine handgeschriebene Schleife schneller ausgeführt werden kann.
Ich kann NormalizeWithSplitAndJoin jedes Mal schlagen, aber nur NormalizeWithRegex mit Eingaben von 1000, 5 schlagen.
Ich habe mir den Maschinencode, den der Jitter erzeugt, nicht angesehen, aber ich gehe davon aus, dass das Problem die Zeit ist, die der Aufruf von StringBuilder.Append () benötigt, und um es besser zu machen, müsste unsicherer Code verwendet werden.
Also ist Regex.Replace () sehr schnell und schwer zu schlagen !!
quelle
VB.NET
C #
Genießen Sie die Leistung von LINQ = D.
quelle
string.Join(" ", myString.Split(' ').Where(s => s != " ").ToArray())
Split
, um alle Leerzeichen zu fangen und dieWhere
Klausel zu entfernen :myString.Split(null as char[], StringSplitOptions.RemoveEmptyEntries)
quelle
Kleinste Lösung:
var regExp = / \ s + / g, newString = oldString.replace (regExp, '');
quelle
Sie können dies versuchen:
quelle
Ersatzgruppen bieten einen impliziten Ansatz, um das Ersetzen mehrerer Leerzeichen durch dasselbe zu lösen :
Bitte beachten Sie, dass das zweite Beispiel einfach bleibt,
\n
während die akzeptierte Antwort das Zeilenende durch Leerzeichen ersetzen würde.Wenn Sie eine Kombination von Leerzeichen durch die erste ersetzen müssen , entfernen Sie einfach die Rückreferenz
\k
aus dem Muster.quelle
Es gibt keine Möglichkeit, dies zu tun. Sie können dies versuchen:
Dadurch werden führende und nachfolgende Leerzeichen entfernt und interne Leerzeichen zu einem einzelnen Leerzeichen zusammengefasst. Wenn Sie wirklich nur Leerzeichen reduzieren möchten, sind die Lösungen mit einem regulären Ausdruck besser. Ansonsten ist diese Lösung besser. (Siehe die Analyse von Jon Skeet.)
quelle
source.ToCharArray()
und wirfst dann das Ergebnis weg?ToCharArray()
auf dem Ergebnis der string.Join, nur eine neue Zeichenfolge zu erstellen ... wow, denn das ist in einem Beitrag zu dem Kopf beschwert nur bemerkenswert ist. -1.whitespace
istnew char[] { ' ' }
, wird dies das falsche Ergebnis , wenn die Eingabezeichenfolge beginnt oder endet mit einem Raum geben.