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

Разделить строку только в первых n вхождения разделителя

Я хотел бы разделить строку только на первые n вхождений разделителя. Я знаю, я мог бы добавить их вместе, используя цикл, но разве нет более прямого подхода?

var string = 'Split this, but not this';    
var result = new Array('Split', 'this,', 'but not this');
4b9b3361

Ответ 1

По MDN:

string.split(separator, limit);

Update:

var string = 'Split this, but not this',
    arr = string.split(' '),
    result = arr.slice(0,2);

result.push(arr.slice(2).join(' ')); // ["Split", "this,", "but not this"]

Обновить версию 2 (один slice короче):

var string = 'Split this, but not this',
    arr = string.split(' '),
    result = arr.splice(0,2);

result.push(arr.join(' ')); // result is ["Split", "this,", "but not this"]

Ответ 2

Использование Array.slice:

function splitWithTail(str,delim,count){
  var parts = str.split(delim);
  var tail = parts.slice(count).join(delim);
  var result = parts.slice(0,count);
  result.push(tail);
  return result;
}

Результаты:

splitWithTail(string," ",2)
// => ["Split", "this,", "but not this"]

Ответ 3

Функция JavaScript ".split()" уже принимает второй параметр, дающий максимальное количество разбиений. Однако он не сохраняет хвост вашей исходной строки; вам придется снова приклеить его.

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

var str = "hello out there cruel world";
var parts = [];
while (parts.length < 3) { // "3" is just an example
  str = str.replace(/^(\w+)\s*(.*)$/, function(_, word, remainder) {
    parts.push(word);
    return remainder;
  });
}
parts.push(str);

edit — и мне просто приходит в голову, что другим простым способом было бы просто использовать ".split()", вырвать первые несколько частей, а затем просто ".slice()" и ".join()" остальные.

Ответ 4

Для этого вы можете использовать Split (разделитель) и выбрать разделитель.

var testSplit = "Split this, but not this";
var testParts= testSplit.Split(",");

var firstPart = testParts[1];

// firstPart = "Split this"

Не на 100% на мой синтаксис Я не использовал javascript довольно долгое время. Но я знаю, что так оно и было...

ИЗМЕНИТЬ ** Извините, моя ошибка. Теперь я верю, что знаю, что вы просите, и я думаю, что самый простой способ сделать это - использовать substr. Очень просто, никаких петель не требуется. Просто сделал пример, отлично работает

// so first, we want to get everything from 0 - the first occurence of the comma.
// next, we want to get everything after the first occurence of the comma.  (if you only define one parameter, substr will take everything after that parameter.

var testString = "Split this, but this part, and this part are one string";
var part1 = testString.substr(0,testString.indexOf(',')); 
var part2 = testString.substr(testString.indexOf(','));

//part1 = "Split this"
//part2= "but this part, and this part are one string"

Ответ 5

Хотя вы можете дать split лимит, вы не получите обратно то, что, как вы сказали, хотите. К сожалению, вам придется перевернуть свои собственные, например:

var string = 'Split this, but not this';
var result = string.split(' ');

if (result.length > 3) {
    result[2] = result.slice(2).join(' ');
    result.length = 3;
}

Но даже тогда вы в конечном итоге изменяете количество пробелов во всех его частях. Поэтому я, вероятно, просто сделаю это старомодным способом write-your-own-loop:

function splitWithLimit(str, delim, limit) {
  var index,
      lastIndex = 0,
      rv = [];

  while (--limit && (index = str.indexOf(delim, lastIndex)) >= 0) {
    rv.push(str.substring(lastIndex, index));
    lastIndex = index + delim.length;
  }
  if (lastIndex < str.length) {
    rv.push(str.substring(lastIndex));
  }
  return rv;
}

Живая копия

Ответ 6

var result = [string.split(' ',1).toString(), string.split(' ').slice(1).join(' ')];

Результаты в:

["Split", "this, but not this"]

Ответ 7

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

String.prototype.split = function(seperator,limit) {
    var value = "";
    var hops  = [];

    // Validate limit
    limit = typeof(limit)==='number'?limit:0;

    // Join back given value
    for ( var i = 0; i < this.length; i++ ) { value += this[i]; }

    // Walkthrough given hops
    for ( var i = 0; i < limit; i++ ) {
        var pos = value.indexOf(seperator);
        if ( pos != -1 ) {
            hops.push(value.slice(0,pos));
            value = value.slice(pos + seperator.length,value.length)

        // Done here break dat
        } else {
            break;
        }
    }
    // Add non processed rest and return
    hops.push(value)
    return hops;
}

В вашем случае это будет выглядеть как

>>> "Split this, but not this".split(' ',2)
["Split", "this,", "but not this"]

Ответ 8

Улучшенная версия правильной реализации limit с надлежащей поддержкой RegEx:

function splitWithTail(value, separator, limit) {
    var pattern, startIndex, m, parts = [];

    if(!limit) {
        return value.split(separator);
    }

    if(separator instanceof RegExp) {
        pattern = new RegExp(separator.source, 'g' + (separator.ignoreCase ? 'i' : '') + (separator.multiline ? 'm' : ''));
    } else {
        pattern = new RegExp(separator.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'), 'g');
    }

    do {
        startIndex = pattern.lastIndex;
        if(m = pattern.exec(value)) {
            parts.push(value.substr(startIndex, m.index - startIndex));
        }
    } while(m && parts.length < limit - 1);
    parts.push(value.substr(pattern.lastIndex));

    return parts;
}

Пример использования:

splitWithTail("foo, bar, baz", /,\s+/, 2); // -> ["foo", "bar, baz"]

Построен для и проверен в Chrome, Firefox, Safari, IE8 +.

Ответ 9

var s='Split this, but not this', a=s.split(','), b=a[0].split(' ');
b.push(a[1]);
alert(b);

alert ['Split', 'this', 'но не это']

Ответ 10

Еще одна реализация, которую я только что написал:

export function split(subject, separator, limit=undefined, pad=undefined) {
    if(!limit) {
        return subject.split(separator);
    }
    if(limit < 0) {
        throw new Error(`limit must be non-negative`);
    }
    let result = [];
    let fromIndex = 0;
    for(let i=1; i<limit; ++i) {
        let sepIdx = subject.indexOf(separator, fromIndex);
        if(sepIdx < 0) {
            break;
        }
        let substr = subject.slice(fromIndex, sepIdx);
        result.push(substr);
        fromIndex = sepIdx + separator.length;
    }
    result.push(subject.slice(fromIndex));
    while(result.length < limit) {
        result.push(pad);
    }
    return result;
}

Не использует регулярные выражения и не перераспределяет и не присоединяется.

Эта версия гарантирует ровно limit элементов (будет размещаться с undefined, если не хватает разделителей); это делает его безопасным для этого типа материала ES6:

let [a,b,c] = split('a$b','$',3,null);
// a = 'a', b = 'b', c = null

Ответ 11

Мне нравится использовать shift.

function splitFirstN(str,n,delim){
    var parts = str.split(delim);
    var r = [];
    for(var i = 0; i < n; i++){
        r.push(parts.shift());
    }
    r.push(parts.join(delim));
    return r;
}

var str = 'Split this, but not this';    
var result = splitFirstN(str,2,' ');

Ответ 12

Комбинация split и join с функциями ES6 делает это довольно аккуратно:

let [str1, str2, ...str3] = string.split(' ');
str3 = str3.join(' ');

Ответ 13

Ни одно простое регулярное выражение не может сделать:

const string = 'Split this, but not this';
console.log(string.match(/^(\S+)\s*(\S+)?\s*([\s\S]+)?$/).slice(1));

Ответ 14

В моем случае я пытался разобрать git grep stdout. Поэтому у меня было {filename}: {linenumber}: {context}. Мне не нравится расщепление, а затем соединение. Мы должны иметь возможность разобрать строку один раз. Вы можете просто пройти каждое письмо и разделить на первые два двоеточия. Более быстрый способ сделать это из коробки - использовать метод совпадения и регулярное выражение.

Следовательно,

txt.match(/(.+):(\d+):(.*)/)

Отлично работает

Ответ 15

Еще одна реализация с ограничением;

// takes string input only
function split(input, separator, limit) {
    input = input.split(separator);
    if (limit) {
        input = input.slice(0, limit - 1).concat(input.slice(limit - 1).join(separator));
    }
    return input;
}