Разделить строку только в первых n вхождения разделителя
Я хотел бы разделить строку только на первые n вхождений разделителя. Я знаю, я мог бы добавить их вместе, используя цикл, но разве нет более прямого подхода?
var string = 'Split this, but not this';
var result = new Array('Split', 'this,', 'but not this');
Ответы
Ответ 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;
}