Jak mogę podzielić ciąg JavaScript białymi znakami lub przecinkami?

123

Jeśli spróbuję

"my, tags are, in here".split(" ,")

Otrzymuję następujące informacje

[ 'my, tags are, in here' ]

Podczas gdy ja chcę

['my', 'tags', 'are', 'in', 'here']
Hoa
źródło
4
nie masz na myśli spacji czy przecinka?
KaptajnKold
1
Jako wyjaśnienie wyniku, który otrzymujesz: "my, tags are, in here".split(" ,")podzieli ciąg tylko wtedy, gdy separatorem jest spacja, po której następuje przecinek. Twój ciąg nie zawiera tej sekwencji, dlatego nie jest podzielony. "my, tags are, in here".split(", ")z zamienioną sekwencją podziału co najmniej podzieli twój oryginalny ciąg na trzy części, po każdym przecinku i spacji. Jeśli potrzebujesz pięciu części, poniższe odpowiedzi określają łańcuch dopasowania jako wyrażenie regularne pasujące do spacji lub przecinka.
Jochem Schulenklopper

Odpowiedzi:

233

String.split może również akceptować wyrażenie regularne:

input.split(/[ ,]+/);

To konkretne wyrażenie regularne dzieli się na sekwencję jednego lub więcej przecinków lub spacji, tak że np. Wiele kolejnych spacji lub sekwencja przecinek + spacja nie daje w wynikach pustych elementów.

Jon
źródło
22
O co chodzi /,?\s+/?
Bergi,
4
@Bergi: Cóż, jest bardziej rygorystyczny niż to, co sugeruję (dozwolony tylko jeden przecinek z przodu) i bardziej luźny (podzielony na wszystkie białe spacje) niż to, o co prosił OP. IMHO byłoby po prostu gorzej - weź pod uwagę wkład spaces , before commas.
Jon
@Jon: OK, to zależy od potrzeb PO. Nie plenk :-)
Bergi
11
+1 Wiem, że to trochę stare, ale po co używać spacji, a nie \s. Mogę mieć kilka podziałów linii w blobie i też się nimi \szajmuję.
iambriansreed
6
FACEPALM UWAGA: nie umieszczaj cudzysłowów wokół wyrażenia regularnego. np. Nie używaj input.split("/[ ,]+/)". Zostaw cudzysłowy ( input.split(//)zamiast input.split("//")), a będziesz miał znacznie lepsze wrażenia. Ponieważ, co dziwne, to naprawdę prawdopodobnie działałoby tylko na siebie (generowanie ["input.split(\"", ")\""]).
cod3monk3y
41

Sugestia użycia .split(/[ ,]+/)jest dobra, ale przy zdaniach naturalnych prędzej czy później otrzymasz puste elementy w tablicy. np ['foo', '', 'bar'].

Co jest w porządku, jeśli jest to w porządku w twoim przypadku użycia. Ale jeśli chcesz pozbyć się pustych elementów, możesz zrobić:

var str = 'whatever your text is...';
str.split(/[ ,]+/).filter(Boolean);
jonschlinkert
źródło
6
To bardzo sprytne użycie natywnych konstruktorów obiektów natywnych - klawiatura mojego komputera jest szalona dziś rano - edytuję ten komentarz później - ale chodzi o wywołanie wartości logicznej, takiej jak 'Boolean ()', skonstruuje nową instancję [object Boolean] z wartość false, podobnie jak wywołanie „new Boolean ()”. Spowoduje to odfiltrowanie wszystkich dopasowań do tego domyślnego zachowania. Niezły :)
VLostBoy
co dokładnie masz na myśli mówiąc „zdania naturalne”? Nie mogłem tego naśladować ani nie rozumiem, co to ma zrobić.
cregox
Wyjaśnia to @VLostBoy. Gdy Boolean()konstruktor jest wywoływany na dowolnej wartości, rzutuje tę wartość na wartość logiczną - prawda lub fałsz. W związku z tym wszelkie fałszywe wartości zostaną odfiltrowane z tablicy, w tym puste ciągi.
jonschlinkert,
1
przy okazji, możesz użyć niejawnych konstruktorów do innych podobnych zabawnych rzeczy, takich jak[1, 2, 3].map(String)
jonschlinkert
2
"foo, bar,,foobar,".split(/[\s,]+/)zwraca ["foo", "bar", "foobar", ""](z powodu wiszącego przecinka na końcu), dzięki!
Rafał Cieślak
37

możesz użyć wyrażenia regularnego, aby złapać dowolną długość spacji, a to wyglądałoby tak:

var text = "hoi how     are          you";
var arr = text.split(/\s+/);

console.log(arr) // will result : ["hoi", "how", "are", "you"]

console.log(arr[2]) // will result : "are" 
Cemil Dogan
źródło
Uważaj na początkowe / końcowe spacje podczas używania /\s+/. Na przykład 'a b c '.split(/\s+/) === [ 'a', 'b', 'c', '' ]. Jeśli .trim()najpierw będziesz szarpać, będziesz dobry.
Jordan Dodson
12
"my, tags are, in here".split(/[ ,]+/)

wynik to :

["my", "tags", "are", "in", "here"]
gabitzish
źródło
4

input.split(/\s*[\s,]\s*/)

\s*Dopasowuje zero lub więcej znaków odstępu (nie tylko spacje, ale także tabulatory i znaki nowej linii).

... [\s,]dopasowuje jeden znak odstępu lub jeden przecinek

Jeśli chcesz uniknąć pustych elementów w danych wejściowych, takich jak "foo,bar,,foobar", to załatwi sprawę:

input.split(/(\s*,?\s*)+/)

+Dopasowuje jeden lub więcej z poprzedniego znaku lub grupy.

Edytować:

Dodano ?po przecinku, który odpowiada zeru lub jednemu przecinkowi.

Edycja 2:

Okazuje się, że edycja 1 była błędem. Naprawione. Teraz musi być co najmniej jeden przecinek lub jedna spacja, aby wyrażenie mogło znaleźć dopasowanie.

KaptajnKold
źródło
Nie. To nie jest dobrze. Oto wynik: ["moje", "tagi są", "tutaj"]
gabitzish
wydaje się rozdzielać na każdym znaku.
Marco
@Marco Oops. Prawdopodobnie powinienem był to przetestować, zanim dokonałem ostatniej edycji. Mam teraz i tym razem naprawdę powinno działać.
KaptajnKold
Hmm, jak to jest lepsze niż zaakceptowana odpowiedź? "foo,bar,foobar".split(/[ ,]+/)wraca ["foo", "bar", "foobar"]również.
Rafał Cieślak
1
@KaptajnKold Och, nie rozumiem, dzięki za odpowiedź!
Rafał Cieślak
2

Gdy chcę wziąć pod uwagę dodatkowe znaki, takie jak przecinki (w moim przypadku każdy token można wprowadzić w cudzysłowach), zrobiłbym string.replace (), aby zmienić pozostałe ograniczniki na puste, a następnie podzielić na białe znaki.

grantwparks
źródło
1
str_variable.replace(/[,'"]+/gi, ' ').split(' ')
qräbnö