Powiedzmy, że mam ciąg taki jak:
"Hello how are you doing?"
Chciałbym mieć funkcję, która zamienia wiele spacji w jedną przestrzeń.
Więc dostałbym:
"Hello how are you doing?"
Wiem, że mógłbym użyć wyrażenia regularnego lub połączenia
string s = "Hello how are you doing?".replace(" "," ");
Ale musiałbym wywoływać to wiele razy, aby upewnić się, że wszystkie kolejne białe znaki są zastąpione tylko jednym.
Czy jest już wbudowana metoda?
c#
string
whitespace
Matt
źródło
źródło
Odpowiedzi:
źródło
To pytanie nie jest tak proste, jak przedstawiają je inne plakaty (i tak mi się początkowo wydawało) - ponieważ nie jest do końca precyzyjne, jak powinno.
Istnieje różnica między „spacją” a „białą spacją”. Jeśli masz na myśli tylko spacje, powinieneś użyć wyrażenia regularnego od
" {2,}"
. Jeśli masz na myśli jakąkolwiek białą spację, to inna sprawa. Powinien wszystko spacje powinny zostać zamienione na spacje? Co powinno się stać z przestrzenią na początku i na końcu?W przypadku testu porównawczego poniżej założyłem, że obchodzą Cię tylko spacje i nie chcesz nic robić z pojedynczymi spacjami, nawet na początku i na końcu.
Zauważ, że poprawność jest prawie zawsze ważniejsza niż wydajność. Fakt, że rozwiązanie Split / Join usuwa wszelkie początkowe / końcowe spacje (nawet tylko pojedyncze spacje) jest niepoprawne, jeśli chodzi o określone wymagania (które oczywiście mogą być niekompletne).
Benchmark wykorzystuje MiniBench .
Kilka testów:
Tutaj pierwsza liczba to liczba iteracji, druga to czas potrzebny, a trzecia to wynik skalowany, przy czym 1.0 to najlepszy.
To pokazuje, że przynajmniej w niektórych przypadkach (w tym w tym jednym) wyrażenie regularne może przewyższać rozwiązanie Split / Join, czasami z bardzo dużym marginesem.
Jednakże, jeśli zmieni się na „wszystko” wymóg spacji, a następnie Split / Dołącz nie wydaje się, aby wygrać. Jak to często bywa, diabeł tkwi w szczegółach ...
źródło
Najłatwiejszym sposobem byłoby zwykłe expressoin. Jeśli napiszesz wyrażenie regularne we właściwy sposób, nie będziesz potrzebować wielu wywołań.
Zmień to na:
źródło
@"\s{2,}"
jest to, że nie zastępuje pojedynczych tabulatorów i innych znaków spacji Unicode spacją. Jeśli zamierzasz zastąpić 2 tabulatory spacją, prawdopodobnie powinieneś zastąpić 1 tabulator spacją.@"\s+"
zrobi to za Ciebie.Chociaż istniejące odpowiedzi są w porządku, chciałbym wskazać jedno podejście, które nie działa:
Może to trwać wiecznie. Czy ktoś chciałby zgadnąć, dlaczego? (Natknąłem się na to tylko wtedy, gdy kilka lat temu zadano to pytanie grupie dyskusyjnej ... ktoś faktycznie napotkał to jako problem.)
źródło
Jak już wspomniano, można to łatwo zrobić za pomocą wyrażenia regularnego. Dodam tylko, że możesz chcieć dodać .trim () do tego, aby pozbyć się początkowych / końcowych białych znaków.
źródło
Oto rozwiązanie, z którym pracuję. Bez RegEx i String.Split.
więc możesz:
źródło
Szybki zmywacz do dodatkowych białych znaków autorstwa Felipe Machado. (Zmodyfikowane przez RW w celu usunięcia wielu przestrzeni)
Wzorce ...
Uwagi dotyczące testów porównawczych: tryb wydania, brak dołączonego debuggera, procesor i7, średnio 4 przebiegi, testowane tylko krótkie ciągi
SwitchStmtBuildSpaceOnly autorstwa Felipe Machado 2015 i zmodyfikowane przez Sunsetquest
InPlaceCharArraySpaceOnly autorstwa Felipe Machado 2015 i zmodyfikowane przez Sunsetquest
SwitchStmtBuild autorstwa Felipe Machado 2015 i zmodyfikowane przez Sunsetquest
SwitchStmtBuild2 autorstwa Felipe Machado 2015 i zmodyfikowane przez Sunsetquest
SingleSpacedTrim autorstwa Davida S 2013
Fubo (StringBuilder) przez fubo 2014
SplitAndJoinOnSpace autorstwa Jona Skeeta 2009
RegExWithCompile autorstwa Jona Skeeta 2009
User214147 użytkownika user214147
RegExBrandon firmy Brandon
RegExNoCompile autorstwa Tima Hoolihana
Kod testu porównawczego znajduje się na Github
źródło
Dzielę się tym, czego używam, bo wygląda na to, że wymyśliłem coś innego. Używam tego od jakiegoś czasu i jest dla mnie wystarczająco szybki. Nie jestem pewien, jak wypada na tle innych. Używam go w rozdzielaczu plików i uruchamiam przez niego duże zbiory danych po jednym polu na raz.
źródło
Korzystając z programu testowego, który opublikował Jon Skeet, próbowałem sprawdzić, czy uda mi się uzyskać ręcznie napisaną pętlę, aby działała szybciej.
Mogę pokonać NormalizeWithSplitAndJoin za każdym razem, ale pokonuję tylko NormalizeWithRegex z wejściami 1000, 5.
Nie patrzyłem na kod maszynowy generowany przez jitter, jednak spodziewam się, że problemem jest czas potrzebny na wywołanie metody StringBuilder.Append () i aby zrobić znacznie lepiej, konieczne byłoby użycie niebezpiecznego kodu.
Więc Regex.Replace () jest bardzo szybki i trudny do pokonania !!
źródło
VB.NET
DO#
Ciesz się mocą LINQ = D
źródło
string.Join(" ", myString.Split(' ').Where(s => s != " ").ToArray())
Split
celu wyłapania wszystkich białych znaków i usunięciaWhere
klauzuli:myString.Split(null as char[], StringSplitOptions.RemoveEmptyEntries)
źródło
Najmniejsze rozwiązanie:
var regExp = / \ s + / g, newString = oldString.replace (regExp, '');
źródło
Możesz spróbować tego:
źródło
Grupy zastępcze zapewniają bardziej kompleksowe podejście do rozwiązywania zastępowania wielu znaków odstępu tym samym pojedynczym:
Proszę zauważyć, że drugi przykład zachowuje pojedynczą wartość,
\n
podczas gdy zaakceptowana odpowiedź zastąpiłaby koniec wiersza spacją.Jeśli chcesz zamienić dowolną kombinację białych znaków na pierwszą, po prostu usuń odniesienie wsteczne
\k
ze wzorca.źródło
Dobrym rozwiązaniem jest również użycie wyrażenia regularnego, aby zastąpić 2 lub więcej białych spacji pojedynczą spacją.
Używamy wzorca regex jako „ \ s + ”.
\ s dopasowuje spację, tabulator, nową linię, powrót karetki, wysuw strony lub tabulator pionowy.
„+” oznacza jedno lub więcej wystąpień.
Przykład Regex
źródło
Nie ma wbudowanego sposobu, aby to zrobić. Możesz spróbować tego:
Spowoduje to usunięcie wiodących i końcowych białych znaków, a także zwinięcie wszelkich wewnętrznych białych znaków do pojedynczego białego znaku. Jeśli naprawdę chcesz zwinąć tylko spacje, lepsze są rozwiązania wykorzystujące wyrażenie regularne; inaczej to rozwiązanie jest lepsze. (Zobacz analizę przeprowadzoną przez Jona Skeeta).
źródło
source.ToCharArray()
a potem odrzucasz wynik?ToCharArray()
wyniku string.Join, tylko po to, aby utworzyć nowy ciąg ... wow, to, że jest w poście narzekającym na narzut, jest po prostu niezwykłe. -1.whitespace
jestnew char[] { ' ' }
, to daje zły wynik, jeśli ciąg wejściowy zaczyna lub kończy się przestrzeń.