Подтвердить что ты не робот

Разделить строку на массив без удаления разделителя?

У меня есть строка вроде

 "asdf a  b c2 "

И я хочу разбить его на массив следующим образом:

["asdf", " ", "a", " ", " ", "b", " ", "c2", " "]

Использование string.split(" ") удаляет пробелы, в результате чего:

["asdf", "a", "", "b", "c2"]

Я думал о вставке дополнительных разделителей, например.

string.replace(/ /g, "| |").replace(/||/g, "|").split("|");

Но это дает неожиданный результат.

4b9b3361

Ответ 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(' ,');