Разделить строку на массив без удаления разделителя?
У меня есть строка вроде
"asdf a b c2 "
И я хочу разбить его на массив следующим образом:
["asdf", " ", "a", " ", " ", "b", " ", "c2", " "]
Использование string.split(" ")
удаляет пробелы, в результате чего:
["asdf", "a", "", "b", "c2"]
Я думал о вставке дополнительных разделителей, например.
string.replace(/ /g, "| |").replace(/||/g, "|").split("|");
Но это дает неожиданный результат.
Ответы
Ответ 1
Вместо того, чтобы расщепляться, было бы легче подумать об этом как об извлечении строк, содержащих либо разделитель, либо последовательные символы, которые не являются разделителем:
'asdf a b c2 '.match(/\S+|\s/g)
// result: ["asdf", " ", "a", " ", " ", "b", " ", "c2", " "]
'asdf a b. . c2% * '.match(/\S+|\s/g)
// result: ["asdf", " ", "a", " ", " ", "b.", " ", ".", " ", "c2%", " ", "*", " "]
Более шекспировское определение совпадений было бы следующим:
'asdf a b c2 '.match(/ |[^ ]+/g)
К
или (не к
) +.
Ответ 2
Использовать позитивный просмотр:
"asdf a b c2 ".split(/(?= )/)
// => ["asdf", " a", " ", " b", " c2", " "]
После редактирования EDIT: Как я уже сказал в комментариях, отсутствие lookbehind делает это немного сложнее. Если все слова состоят только из букв, вы можете подделать lookbehind с помощью \b
разделителя границ слов:
"asdf a b c2 ".split(/(?= )|\b/)
// => ["asdf", " ", "a", " ", " ", "b", " ", "c2", " "]
но как только вы получите некоторую пунктуацию, он ломается, поскольку он не только разбивается на пробелы:
"asdf-eif.b".split(/(?= )|\b/)
// => ["asdf", "-", "eif", ".", "b"]
Если у вас есть не буквы, которые вы не хотите ломать, тогда я также предлагаю метод постобработки.
Post-think EDIT. Это основано на оригинальной идее JamesA, но уточняется, что нельзя использовать jQuery и правильно разделить:
function chop(str) {
var result = [];
var pastFirst = false;
str.split(' ').forEach(function(x) {
if (pastFirst) result.push(' ');
if (x.length) result.push(x);
pastFirst = true;
});
return result;
}
chop("asdf a b c2 ")
// => ["asdf", " ", "a", " ", " ", "b", " ", "c2", " "]
Ответ 3
Я удивлен, что никто не упомянул об этом, но я отправлю это здесь ради полноты. Если у вас есть группы захвата в выражении, то .split
будет включать захваченную подстроку в виде отдельной записи в массиве результатов:
"asdf a b c2 ".split(/( )/) // or /(\s)/
// ["asdf", " ", "a", " ", "", " ", "b", " ", "c2", " ", ""]
Обратите внимание: это не совсем то же самое, что и желаемый вывод, который вы указали, поскольку он содержит пустую строку между двумя смежными пробелами и после последнего пробела.
При необходимости вы можете отфильтровать все пустые строки из массива результатов следующим образом:
"asdf a b c2 ".split(/( )/).filter(String)
// ["asdf", " ", "a", " ", " ", "b", " ", "c2", " "]
Однако, если это то, что вы ищете, я бы, вероятно, порекомендовал вам пойти с @Jack solution.
Ответ 4
Вы можете использовать небольшой jQuery
var toSplit = "asdf a b c2 ".split(" ");
$.each(toSplit,
function(index, value) {
if (toSplit[index] == '') { toSplit[index] = ' '}
}
);
Это создаст вывод, который вы ищете, без ведущих пробелов для других элементов.
Ответ 5
"asdf a b c2 ".split(' ').join(' ,');