Как разбить строку JavaScript пробелом или запятой?

123

Если я попробую

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

Я получаю следующее

[ 'my, tags are, in here' ]

А я хочу

['my', 'tags', 'are', 'in', 'here']
Хоа
источник
4
вы не имеете в виду пробелы или запятую?
KaptajnKold
1
В качестве объяснения результата, который вы получаете: "my, tags are, in here".split(" ,")разделит строку только там, где пробел, за которым следует запятая, является разделителем. Ваша строка не содержит этой последовательности, поэтому она не разбита. "my, tags are, in here".split(", ")с замененной последовательностью разбиения, ваша исходная строка будет как минимум разделена на три части после каждой запятой и пробела. Если вам нужно пять частей, в приведенных ниже ответах строка соответствия указывается в виде регулярного выражения, соответствующего пробелу или запятой.
Jochem Schulenklopper

Ответы:

233

String.split также может принимать регулярное выражение:

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

Это конкретное регулярное выражение разбивается на последовательность из одной или нескольких запятых или пробелов, так что, например, несколько последовательных пробелов или последовательность запятая + пробел не приводят к появлению пустых элементов в результатах.

Джон
источник
22
О чем /,?\s+/?
Берги
4
@Bergi: Ну, это и более строго, чем то, что я предлагаю (разрешена только одна запятая впереди), и более свободное (разделено на все пробелы), чем то, что просил OP. ИМХО было бы просто хуже - считайте ввод spaces , before commas.
Джон
@Jon: Хорошо, это зависит от потребностей OP. Я бы не стал пленк :-)
Берги
11
+1 Я знаю, что это старовато, но зачем использовать пробел, а не \s. У меня могут быть разрывы строк в BLOB-объекте, и я \sтоже позабочусь о них.
iambriansreed
6
ПРИМЕЧАНИЕ: НЕ заключайте регулярное выражение в кавычки. например, не используйте input.split("/[ ,]+/)". Оставьте цитаты ( input.split(//)вместо input.split("//")), и вы получите гораздо лучший опыт. Потому что, как ни странно, это действительно, вероятно, будет работать только само по себе (для генерации ["input.split(\"", ")\""]).
cod3monk3y
41

Предложение использовать .split(/[ ,]+/)хорошо, но с естественными предложениями рано или поздно вы получите пустые элементы в массиве. напр ['foo', '', 'bar'].

Что нормально, если это подходит для вашего варианта использования. Но если вы хотите избавиться от пустых элементов, вы можете:

var str = 'whatever your text is...';
str.split(/[ ,]+/).filter(Boolean);
jonschlinkert
источник
6
Это очень умное использование неявных конструкторов нативных объектов - клавиатура моего компьютера сегодня безумна - я отредактирую этот комментарий позже - но точка вызывает логическое значение, например, 'Boolean ()' создаст новый экземпляр [object Boolean] с значение false, точно так же, как при вызове 'new Boolean ()'. Это отфильтрует все совпадения до этого поведения по умолчанию. Хороший :)
VLostBoy
что именно вы подразумеваете под «естественными предложениями»? Я не мог подражать этому и не понимаю, что это должно делать.
cregox
Это объясняет @VLostBoy. Когда Boolean()конструктор вызывается для любого значения, он преобразует это значение в логическое значение - истина или ложь. Таким образом, любые ложные значения будут отфильтрованы из массива, включая пустые строки.
jonschlinkert
1
кстати, вы можете использовать неявные конструкторы для других подобных забавных вещей, например[1, 2, 3].map(String)
jonschlinkert
2
"foo, bar,,foobar,".split(/[\s,]+/)возвращается ["foo", "bar", "foobar", ""](из-за запятой в конце), спасибо!
Рафал
37

вы можете использовать регулярное выражение, чтобы поймать любую длину пробела, и это будет примерно так:

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" 
Джемил Доган
источник
Остерегайтесь начальных / конечных пробелов при использовании /\s+/. Например, 'a b c '.split(/\s+/) === [ 'a', 'b', 'c', '' ]. Если вы .trim()сначала натянете струну, все будет хорошо.
Jordan Dodson
12
"my, tags are, in here".split(/[ ,]+/)

результат:

["my", "tags", "are", "in", "here"]
gabitzish
источник
4

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

\s*Соответствует нулю или более пробелов (не только пробелов, но также табуляции и новой строки).

... [\s,]соответствует одному символу пробела или одной запятой

Если вы хотите избежать пустых элементов из ввода, например "foo,bar,,foobar", это поможет:

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

Соответствует +одному или нескольким предыдущим символам или группам.

Редактировать:

Добавляется ?после запятой, которая соответствует нулю или одной запятой.

Изменить 2:

Оказывается, редактирование 1 было ошибкой. Починил это. Теперь должна быть хотя бы одна запятая или один пробел, чтобы выражение могло найти совпадение.

KaptajnKold
источник
Nop. Это не хорошо. Это результат: ["мой", "теги", "здесь"]
gabitzish
кажется, что он разделен на каждого персонажа.
Марко
@Marco Упс. Наверное, следовало протестировать его, прежде чем я сделал это последнее редактирование. У меня есть сейчас, и на этот раз это действительно должно сработать.
KaptajnKold
Хм, чем это лучше принятого ответа? тоже "foo,bar,foobar".split(/[ ,]+/)возвращается ["foo", "bar", "foobar"].
Рафал
1
@KaptajnKold О, я не расслышал, спасибо за ответ!
Рафал
2

Когда я хочу учесть дополнительные символы, такие как ваши запятые (в моем случае каждый токен может быть введен в кавычки), я бы сделал string.replace (), чтобы изменить другие разделители на пробелы, а затем разделить их на пробелы.

grantwparks
источник
1
str_variable.replace(/[,'"]+/gi, ' ').split(' ')
qräbnö