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

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


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.


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, " ");

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.


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, "")


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


1

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

text.replace(/[\W_-]/g,' ');

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;
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.