Zastąp wszystkie znaki inne niż alfanumeryczne, nowe wiersze i wiele białych znaków jedną spacją

141

Szukam zgrabnego rozwiązania RegEx do wymiany

  • Wszystkie znaki inne niż alfanumeryczne
  • Wszystkie nowe linie
  • Wszystkie wielokrotne wystąpienia białych znaków

Z jedną spacją


Dla osób grających w domu (działają poniższe zasady )

text.replace(/[^a-z0-9]/gmi, " ").replace(/\s+/g, " ");

Myślę, że RegEx jest prawdopodobnie wystarczająco potężny, aby osiągnąć to w jednym stwierdzeniu. Sądzę, że potrzebne są komponenty

  • [^a-z0-9] - aby usunąć znaki inne niż alfanumeryczne
  • \s+ - dopasuj dowolne kolekcje przestrzeni
  • \r?\n|\r - dopasuj wszystkie nowe linie
  • /gmi - globalne, wielowierszowe, bez rozróżniania wielkości liter

Jednak nie mogę stylizować wyrażenia regularnego we właściwy sposób ( nie działa poniższy sposób )

text.replace(/[^a-z0-9]|\s+|\r?\n|\r/gmi, " ");


Wejście

234&^%,Me,2 2013 1080p x264 5 1 BluRay
S01(*&asd 05
S1E5
1x05
1x5


Pożądane wyjście

234 Me 2 2013 1080p x264 5 1 BluRay S01 asd 05 S1E5 1x05 1x5
Generał
źródło
Jak dokładnie twoja próba nie działa? Co się stało?
Pointy

Odpowiedzi:

245

Należy pamiętać, że \W pozostawia to podkreślenie . Krótkim odpowiednikiem [^a-zA-Z0-9]byłoby[\W_]

text.replace(/[\W_]+/g," ");

\Wjest zaprzeczeniem skrót \w do [A-Za-z0-9_]znaków słownych (w tym podkreślenie)

Przykład na regex101.com

Jonny 5
źródło
Sprawdź i przetestuj, nie masz jeszcze dużego doświadczenia w js-regex: p Happy you like it
Jonny 5
6
Zauważ, że \Wrozpoznają również znaki spoza alfabetu łacińskiego jako znaki niebędące słowami.
Tyblitz
1
Oznaczyłem tę odpowiedź jako poprawną po tych wszystkich latach, ponieważ spojrzałem wstecz i zaakceptowane nie wykluczały podkreślenia
The General
145

Jonny 5 mnie pokonał. Miałem zamiar zasugerować użycie \W+bez \sjak w text.replace(/\W+/g, " "). Obejmuje to również białe znaki.

T-CatSan
źródło
Dzięki @ T-CatSan za wskazanie tego! Podnieś to i Saruman, możesz zmienić najlepszą odpowiedź na cokolwiek :-) Ale powinno być \W+, nie [W+]Cóż, szczęśliwego nowego roku!
Jonny 5
Dzięki, @ Jonny5! Dokonałem zaproponowanej przez Ciebie zmiany. Testowałem wcześniej z zamkami i teraz widzę, że działa bez nich. Tobie również szczęśliwego Nowego Roku.
T-CatSan
1
hej @ T-CatSan czy istnieje sposób na dodanie wyjątków? Chcę zachować postacie &i -. Jakieś wskazówki?
Renato Gama
1
Dokonałem następującej zmiany / (\ W +) | (_) / g, aby również zignorować _. Zastanawiam się tylko, dlaczego nie jest ignorowany w pierwszym modelu i czy moje wyrażenie regularne jest wydajne.
Sridhar Gudimela
15

Ponieważ [^a-z0-9]klasa znaków zawiera wszystko, co nie jest alnum, zawiera również białe znaki!

 text.replace(/[^a-z0-9]+/gi, " ");
Casimir et Hippolyte
źródło
8

Myślę, że wystarczy dodać kwantyfikator do każdego wzorca. Trochę zabawna jest też sprawa powrotu karetki:

text.replace(/[^a-z0-9]+|\s+/gmi, " ");

edycji The \smecze rzeczą \ri \nzbyt.

Spiczasty
źródło
Tak, było tam trochę głupców zebranych z innych odpowiedzi na ten temat, jednak to działa świetnie, dzięki!
Generał
4

A zobaczył inny post, który również miał znaki diakrytyczne, co jest świetne

s.replace(/[^a-zA-Z0-9À-ž\s]/g, "")

Dmitri R117
źródło
3

To jest mój stary post, zaakceptowane odpowiedzi są w większości dobre. Jednak zdecydowałem się przetestować każde rozwiązanie i jedno oczywiste (dla zabawy). Zastanawiałem się, czy istnieje różnica między wzorcami regex w różnych przeglądarkach z ciągami o różnych rozmiarach.

Więc w zasadzie użyłem jsPerf na

  • Testowanie w Chrome 65.0.3325 / Windows 10 0.0.0
  • Testowanie w Edge 16.16299.0 / Windows 10 0.0.0

Testowane przeze mnie wzorce regex to

  • /[\W_]+/g
  • /[^a-z0-9]+/gi
  • /[^a-zA-Z0-9]+/g

Załadowałem je z ciągiem losowych znaków

  • długość 5000
  • długość 1000
  • długość 200

Przykład javascript, którego użyłem var newstr = str.replace(/[\W_]+/g," ");

Każdy przebieg składał się z 50 lub więcej próbek w każdym wyrażeniu regularnym i uruchamiam je 5 razy w każdej przeglądarce.

Ścigajmy się z naszymi końmi!

Wyniki

                                Chrome                  Edge
Chars   Pattern                 Ops/Sec     Deviation   Op/Sec      Deviation
------------------------------------------------------------------------
5,000   /[\W_]+/g                19,977.80  1.09         10,820.40  1.32
5,000   /[^a-z0-9]+/gi           19,901.60  1.49         10,902.00  1.20
5,000   /[^a-zA-Z0-9]+/g         19,559.40  1.96         10,916.80  1.13
------------------------------------------------------------------------
1,000   /[\W_]+/g                96,239.00  1.65         52,358.80  1.41
1,000   /[^a-z0-9]+/gi           97,584.40  1.18         52,105.00  1.60
1,000   /[^a-zA-Z0-9]+/g         96,965.80  1.10         51,864.60  1.76
------------------------------------------------------------------------
  200   /[\W_]+/g               480,318.60  1.70        261,030.40  1.80
  200   /[^a-z0-9]+/gi          476,177.80  2.01        261,751.60  1.96
  200   /[^a-zA-Z0-9]+/g        486,423.00  0.80        258,774.20  2.15

Prawdę mówiąc, Regex w obu przeglądarkach (biorąc pod uwagę odchylenia) były prawie nie do odróżnienia, jednak myślę, że gdyby uruchomił to jeszcze więcej razy, wyniki stałyby się trochę jaśniejsze (ale nie za dużo).

Teoretyczne skalowanie dla 1 znaku

                            Chrome                        Edge
Chars   Pattern             Ops/Sec     Scaled            Op/Sec    Scaled
------------------------------------------------------------------------
5,000   /[\W_]+/g            19,977.80  99,889,000       10,820.40  54,102,000
5,000   /[^a-z0-9]+/gi       19,901.60  99,508,000       10,902.00  54,510,000
5,000   /[^a-zA-Z0-9]+/g     19,559.40  97,797,000       10,916.80  54,584,000
------------------------------------------------------------------------

1,000   /[\W_]+/g            96,239.00  96,239,000       52,358.80  52,358,800
1,000   /[^a-z0-9]+/gi       97,584.40  97,584,400       52,105.00  52,105,000
1,000   /[^a-zA-Z0-9]+/g     96,965.80  96,965,800       51,864.60  51,864,600
------------------------------------------------------------------------

  200   /[\W_]+/g           480,318.60  96,063,720      261,030.40  52,206,080
  200   /[^a-z0-9]+/gi      476,177.80  95,235,560      261,751.60  52,350,320
  200   /[^a-zA-Z0-9]+/g    486,423.00  97,284,600      258,774.20  51,754,840

Nie wziąłbym zbyt wiele na te wyniki, ponieważ nie są to tak naprawdę znaczące różnice, jedyne, co naprawdę możemy powiedzieć, to to, że krawędź jest wolniejsza: o. Poza tym byłam super znudzona.

W każdym razie możesz samodzielnie przeprowadzić test porównawczy.

Jsperf Benchmark tutaj

Generał
źródło
1

Aby zastąpić myślnikami, wykonaj następujące czynności:

text.replace(/[\W_-]/g,' ');
Gregory R.
źródło
1

Dla każdego, kto nadal ma problemy (jak ja ...) po powyższych odpowiedziach ekspertów, działa to w programie Visual Studio 2019:

outputString = Regex.Replace(inputString, @"\W", "_");

Pamiętaj, aby dodać

using System.Text.RegularExpressions;
egginstone
źródło