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!");