76

How can I split a string without removing the delimiters?

Let's say I have a string: var string = "abcdeabcde";

When I do var newstring = string.split("d"), I get something like this:

["abc","eabc","e"]

But I want to get this:

["abc","d","eabc","d","e"]

When I tried to do my "split2" function, I got all entangled in splice() and indexes and "this" vs "that" and ... aargh! Help! :D

scottt
  • 7,008
  • 27
  • 37
Martin Janiczek
  • 2,996
  • 3
  • 24
  • 32
  • @ruffin It's not marked but has the same comment pointing back here. They are both *suggested* as duplicates of each other - we should somehow make up our minds which one to close :) – BartoszKP Nov 26 '18 at 20:35

10 Answers10

85

Try:

"abcdeabcde".split(/(d)/);
Kai
  • 9,038
  • 5
  • 28
  • 28
41

I like Kai's answer, but it's incomplete. Instead use:

"abcdeabcde".split(/(?=d)/g) //-> ["abc", "deabc", "de"]

This is using a Lookahead Zero-Length Assertion in regex, which makes a match not part of the capture group. No other tricks or workarounds needed.

micha
  • 1,036
  • 8
  • 12
  • 2
    Is there a solution to get this result : //-> ["abcd", "eabcd", "e"] – forresst Sep 19 '19 at 08:39
  • @forresst Not with a single split command, AFAIK. But the accepted answer oddly enough does almost that, except with leading delimiters in stead of trailing. – Joachim Lous Oct 23 '19 at 13:37
  • 4
    @forresst @JoachimLous You can just use a lookbehind approach, which is also described on the page linked by micha. E.g.: `"abcdeabcde".split(/(?<=d)/g)` – F Lekschas Jan 21 '22 at 21:37
37

Try this:

  1. Replace all of the "d" instances into ",d"
  2. Split by ","
var string = "abcdeabcde";
var newstringreplaced = string.replace(/d/gi, ",d");
var newstring = newstringreplaced.split(",");
return newstring;

Hope this helps.

mplungjan
  • 169,008
  • 28
  • 173
  • 236
InfoLearner
  • 14,952
  • 20
  • 76
  • 124
21
var parts= string.split('d');
for (var i= parts.length; i-->1;)
    parts.splice(i, 0, 'd');

(The reversed loop is necessary to avoid adding ds to parts of the list that have already had ds inserted.)

bobince
  • 528,062
  • 107
  • 651
  • 834
5

split - split is used to create separate lines not for searching.

[^d] - find a group of substrings not containing "d"

var str = "abcdeabcde";

str.match(/[^d]+|d/g)         // ["abc", "d", "eabc", "d", "e"]
or
str.match(/[^d]+/g)           // ["abc", "eabc", "e"]
or
str.match(/[^d]*/g)           // ["abc", "", "eabc", "", "e", ""]

Read "RegExp Object" if you do not want problems with the "javascript".

udn79
  • 51
  • 1
  • 2
  • No problem. I've tried make it a little clearer. Please feel free to rollback or edit if I've made a mistake. – Conrad Frix Dec 10 '12 at 23:06
  • Global objects change affects the speed. Methods "RegExp" - versatile and quick. If the code is large, it is easier to understand the code. This is my opinion. – udn79 Dec 10 '12 at 23:17
4

This is my version for regexp delimiters. It has same interface with String.prototype.split; it will treat global and non global regexp with no difference. Returned value is an array that odd member of it are matched delimiters.

function split(text, regex) {
    var token, index, result = [];
    while (text !== '') {
        regex.lastIndex = 0;
        token = regex.exec(text);
        if (token === null) {
            break;
        }
        index = token.index;
        if (token[0].length === 0) {
            index = 1;
        }
        result.push(text.substr(0, index));
        result.push(token[0]);
        index = index + token[0].length;
        text = text.slice(index);
    }
    result.push(text);
    return result;
}

// Tests
assertEquals(split("abcdeabcde", /d/), ["abc", "d", "eabc", "d", "e"]);
assertEquals(split("abcdeabcde", /d/g), ["abc", "d", "eabc", "d", "e"]);
assertEquals(split("1.2,3...4,5", /[,\.]/), ["1", ".", "2", ",", "3", ".", "", ".", "", ".", "4", ",", "5"]);
assertEquals(split("1.2,3...4,5", /[,\.]+/), ["1", ".", "2", ",", "3", "...", "4", ",", "5"]);
assertEquals(split("1.2,3...4,5", /[,\.]*/), ["1", "", "", ".", "2", "", "", ",", "3", "", "", "...", "4", "", "", ",", "5", "", ""]);
assertEquals(split("1.2,3...4,5", /[,\.]/g), ["1", ".", "2", ",", "3", ".", "", ".", "", ".", "4", ",", "5"]);
assertEquals(split("1.2,3...4,5", /[,\.]+/g), ["1", ".", "2", ",", "3", "...", "4", ",", "5"]);
assertEquals(split("1.2,3...4,5", /[,\.]*/g), ["1", "", "", ".", "2", "", "", ",", "3", "", "", "...", "4", "", "", ",", "5", "", ""]);
assertEquals(split("1.2,3...4,5.", /[,\.]/), ["1", ".", "2", ",", "3", ".", "", ".", "", ".", "4", ",", "5", ".", ""]);
assertEquals(split("1.2,3...4,5.", /[,\.]+/), ["1", ".", "2", ",", "3", "...", "4", ",", "5", ".", ""]);
assertEquals(split("1.2,3...4,5.", /[,\.]*/), ["1", "", "", ".", "2", "", "", ",", "3", "", "", "...", "4", "", "", ",", "5", "", "", ".", ""]);
assertEquals(split("1.2,3...4,5.", /[,\.]/g), ["1", ".", "2", ",", "3", ".", "", ".", "", ".", "4", ",", "5", ".", ""]);
assertEquals(split("1.2,3...4,5.", /[,\.]+/g), ["1", ".", "2", ",", "3", "...", "4", ",", "5", ".", ""]);
assertEquals(split("1.2,3...4,5.", /[,\.]*/g), ["1", "", "", ".", "2", "", "", ",", "3", "", "", "...", "4", "", "", ",", "5", "", "", ".", ""]);

// quick and dirty assert check
function assertEquals(actual, expected) {
  console.log(JSON.stringify(actual) === JSON.stringify(expected));
}
Ebrahim Byagowi
  • 10,338
  • 4
  • 70
  • 81
2

Try this:

var string = "abcdeabcde";
    var delim = "d";
    var newstring = string.split(delim);
    var newArr = [];
    var len=newstring.length;
    for(i=0; i<len;i++)
    {
        newArr.push(newstring[i]);
        if(i != len-1)newArr.push(delim);
    }
Chandu
  • 81,493
  • 19
  • 133
  • 134
0
function split2(original){
   var delimiter = "d", result = [], tmp;
   tmp = original.split(delimiter);
   tmp.forEach(function(x){result.push(x); result.push(delimiter); });
   return result;
}
pc1oad1etter
  • 8,549
  • 10
  • 49
  • 64
0

Try this

"abcdeabcde".split("d").reduce((result, value, index) => {
    return (index !== 0) ? result.concat(["d", value]) : result.concat(value)
}, [])
heesu Suh
  • 9
  • 2
-1

Try this

var string = "abcdeabcde";
var res = string.replace( /d/g, 'd\0' ).split(/(?=d)|\0/);
console.log( res );
//["abc", "d", "eabc", "d", "e"]
meouw
  • 41,754
  • 10
  • 52
  • 69