I\'d like to split a string only the at the first n occurrences of a delimiter. I know, I could add them together using a loop, but isn\'t there a more straight forward appr
For this you could use Split(delimiter) and choose a delimiter.
var testSplit = "Split this, but not this";
var testParts= testSplit.Split(",");
var firstPart = testParts[1];
// firstPart = "Split this"
Not 100% on my syntax I havent used javascript in quite some time. But I know this is how its done...
EDIT** Sorry, my mistake. Now I believe I know what your asking and I think the easiest way to do this is using substr. Very easy, no loops required. Just made an example, works perfect
// 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"
As per 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"]
Update version 2 (one slice
shorter):
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"]
Nothing a one simple regex can't do:
const string = 'Split this, but not this';
console.log(string.match(/^(\S+)\s*(\S+)?\s*([\s\S]+)?$/).slice(1));
My version, universal, supports RegExp and non-RegExp delimiters. Highly optimized. Tests provided. Why: since other RegExp versions are full of bugs and this is not a trivial function.
Usage:
"a b c d".split_with_tail(/ +/,3) = ['a','b','c d']
"a b c d".split_with_tail(' ',3) = ['a','b',' c d']
Code
String.prototype.split_with_tail = function(delimiter,limit)
{
if( typeof(limit) !== 'number' || limit < 1 ) return this.split(delimiter,limit);
var parts = this.split(delimiter,limit+1);
if( parts.length <= limit ) return parts;
parts.splice(-2,2);
limit = Math.floor(limit) - 1; // used later as index, speed optimization; limit can be float ..
if( delimiter instanceof RegExp ) {
// adds 'g' flag to any regexp:
delimiter += '';
var len = delimiter.lastIndexOf('/');
delimiter = new RegExp(delimiter.slice(1, len), delimiter.slice(len + 1)+'g');
len = 0;
while(limit--) len += parts[limit].length + (delimiter.exec(this))[0].length;
}
else {
var len = limit * (''+delimiter).length;
while(limit--) len += parts[limit].length;
}
parts.push(this.substring(len)); // adds tail, finally
return parts;
}
Tests
function test(str,delimiter,limit,result) {
if( JSON.stringify(result) !== JSON.stringify(str.split_with_tail(delimiter,limit)) ) {
console.log(arguments);
console.log(str.split_with_tail(delimiter,limit));
throw "lol";
}
}
test('',/ +/,undefined,['']);
test('',/ +/,3,['']);
test('a',/ +/,0.1,[]);
test('a',/ +/,1,['a']);
test('a a',/ +/,1,['a a']);
test('a a',/ +/,2.1,['a','a']);
test('a a a',/ +/,2.9,['a','a a']);
test('aaaaa aa a',/ +/,1,['aaaaa aa a']);
test('aaaaa aa a',/ +/,2,['aaaaa', 'aa a']);
test('a a',/ +/,2,['a','a']);
test('a',/ +/,3,['a']);
test('a a',/ +/,3,['a','a']);
test('a a a',/ +/,3,['a','a','a']);
test('a a a a',/ +/,3,['a','a','a a']);
test('a a a a',/ +/,4,['a','a','a','a']);
test('a aa aaa ',/ +/,4,['a','aa','aaa','']);
test('a a a a',/ +/,2,['a','a a a']);
test('a a a a',/ +/,1,['a a a a']);
test('a a a a',/ +/,0,[]);
test('a a a a',/ +/,undefined,['a','a','a','a']);
test('a a a a',/ +/,-1,['a','a','a','a']);
test('a',' ',3,['a']);
test('aaaaa aa a',' ',2,['aaaaa', 'aa a']);
test('aaaaa aa a',' ',2,['aaaaa','aa a']);
test('a a a',' ',3,['a','a','a']);
test('a a a a',' ',3,['a','a','a a']);
test('a a a a',' ',3,['a','a',' a a']);
test('a a a a',' ',2,['a','a a a']);
test('a a a a',' ',1,['a a a a']);
test('a a a a',' ',0,[]);
test('a a a a',' ',undefined,['a','a','','a','a']);
test('a a a a',' ',-1,['a','a','','a','a']);
test('1232425',2,3,['1','3','425']);
console.log("good!");
Yet another implementation I just wrote:
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;
}
Doesn't use regexes, nor does it over-split and re-join.
This version guarantees exactly limit
elements (will pad with undefined
s if there aren't enough separators); this makes it safe to do this kind of ES6 stuff:
let [a,b,c] = split('a$b','$',3,null);
// a = 'a', b = 'b', c = null
I like using 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,' ');