How do I split a string with multiple separators in JavaScript?

JavascriptRegexSplit

Javascript Problem Overview


How do I split a string with multiple separators in JavaScript?

I'm trying to split on both commas and spaces, but AFAIK JavaScript's split() function only supports one separator.

Javascript Solutions


Solution 1 - Javascript

Pass in a regexp as the parameter:

js> "Hello awesome, world!".split(/[\s,]+/)
Hello,awesome,world!

Edited to add:

You can get the last element by selecting the length of the array minus 1:

>>> bits = "Hello awesome, world!".split(/[\s,]+/)
["Hello", "awesome", "world!"]
>>> bit = bits[bits.length - 1]
"world!"

... and if the pattern doesn't match:

>>> bits = "Hello awesome, world!".split(/foo/)
["Hello awesome, world!"]
>>> bits[bits.length - 1]
"Hello awesome, world!"

Solution 2 - Javascript

You can pass a regex into JavaScript's split() method. For example:

"1,2 3".split(/,| /) 
["1", "2", "3"]

Or, if you want to allow multiple separators together to act as one only:

"1, 2, , 3".split(/(?:,| )+/) 
["1", "2", "3"]

(You have to use the non-capturing (?:) parenthesis, because otherwise it gets spliced back into the result. Or you can be smart like Aaron and use a character class.)

Examples tested in Safari and Firefox.

Solution 3 - Javascript

Another simple but effective method is to use split + join repeatedly.

"a=b,c:d".split('=').join(',').split(':').join(',').split(',')

Essentially doing a split followed by a join is like a global replace so this replaces each separator with a comma then once all are replaced it does a final split on comma

The result of the above expression is:

['a', 'b', 'c', 'd']

Expanding on this you could also place it in a function:

function splitMulti(str, tokens){
		var tempChar = tokens[0]; // We can use the first token as a temporary join character
		for(var i = 1; i < tokens.length; i++){
			str = str.split(tokens[i]).join(tempChar);
		}
		str = str.split(tempChar);
		return str;
}

Usage:

splitMulti('a=b,c:d', ['=', ',', ':']) // ["a", "b", "c", "d"]

If you use this functionality a lot it might even be worth considering wrapping String.prototype.split for convenience (I think my function is fairly safe - the only consideration is the additional overhead of the conditionals (minor) and the fact that it lacks an implementation of the limit argument if an array is passed).

Be sure to include the splitMulti function if using this approach to the below simply wraps it :). Also worth noting that some people frown on extending built-ins (as many people do it wrong and conflicts can occur) so if in doubt speak to someone more senior before using this or ask on SO :)

    var splitOrig = String.prototype.split; // Maintain a reference to inbuilt fn
	String.prototype.split = function (){
		if(arguments[0].length > 0){
			if(Object.prototype.toString.call(arguments[0]) == "[object Array]" ) { // Check if our separator is an array
				return splitMulti(this, arguments[0]);  // Call splitMulti
			}
		}
		return splitOrig.apply(this, arguments); // Call original split maintaining context
	};

Usage:

var a = "a=b,c:d";
	a.split(['=', ',', ':']); // ["a", "b", "c", "d"]

// Test to check that the built-in split still works (although our wrapper wouldn't work if it didn't as it depends on it :P)
    	a.split('='); // ["a", "b,c:d"] 

Enjoy!

Solution 4 - Javascript

Lets keep it simple: (add a "[ ]+" to your RegEx means "1 or more")

This means "+" and "{1,}" are the same.

var words = text.split(/[ .:;?!~,`"&|()<>{}\[\]\r\n/\\]+/); // note ' and - are kept

Solution 5 - Javascript

Tricky method:

var s = "dasdnk asd, (naks) :d skldma";
var a = s.replace('(',' ').replace(')',' ').replace(',',' ').split(' ');
console.log(a);//["dasdnk", "asd", "naks", ":d", "skldma"]

Solution 6 - Javascript

For those of you who want more customization in their splitting function, I wrote a recursive algorithm that splits a given string with a list of characters to split on. I wrote this before I saw the above post. I hope it helps some frustrated programmers.

splitString = function(string, splitters) {
	var list = [string];
	for(var i=0, len=splitters.length; i<len; i++) {
		traverseList(list, splitters[i], 0);
	}
	return flatten(list);
}

traverseList = function(list, splitter, index) {
	if(list[index]) {
		if((list.constructor !== String) && (list[index].constructor === String))
			(list[index] != list[index].split(splitter)) ? list[index] = list[index].split(splitter) : null;
		(list[index].constructor === Array) ? traverseList(list[index], splitter, 0) : null;
		(list.constructor === Array) ? traverseList(list, splitter, index+1) : null;	
	}
}

flatten = function(arr) {
    return arr.reduce(function(acc, val) {
        return acc.concat(val.constructor === Array ? flatten(val) : val);
    },[]);
}

var stringToSplit = "people and_other/things";
var splitList = [" ", "_", "/"];
splitString(stringToSplit, splitList);

Example above returns: ["people", "and", "other", "things"]

Note: flatten function was taken from Rosetta Code

Solution 7 - Javascript

I'm suprised no one has suggested it yet, but my hack-ey (and crazy fast) solution was to just append several 'replace' calls before splitting by the same character.

i.e. to remove a, b, c, d, and e:

let str = 'afgbfgcfgdfgefg'
let array = str.replace('a','d').replace('b','d').replace('c','d').replace('e','d').split('d')

this can be conveniently generalized for an array of splitters as follows:

function splitByMany( manyArgs, string ) {
  do {
    let arg = manyArgs.pop()
    string = string.replace(arg, manyArgs[0])
  } while (manyArgs.length > 2)
  return string.split(manyArgs[0])
}

So, in your case, you could then call

let array = splitByMany([" ", ","], 'My long string containing commas, and spaces, and more commas');

Solution 8 - Javascript

You could just lump all the characters you want to use as separators either singularly or collectively into a regular expression and pass them to the split function. For instance you could write:

console.log( "dasdnk asd, (naks) :d skldma".split(/[ \(,\)]+/) );

And the output will be:

["dasdnk", "asd", "naks", ":d", "skldma"]

Solution 9 - Javascript

My refactor of @Brian answer

var string = 'and this is some kind of information and another text and simple and some egample or red or text';
var separators = ['and', 'or'];

function splitMulti(str, separators){
            var tempChar = 't3mp'; //prevent short text separator in split down
            
            //split by regex e.g. \b(or|and)\b
            var re = new RegExp('\\b(' + separators.join('|') + ')\\b' , "g");
            str = str.replace(re, tempChar).split(tempChar);
            
            // trim & remove empty
            return str.map(el => el.trim()).filter(el => el.length > 0);
}

console.log(splitMulti(string, separators))

Solution 10 - Javascript

Here are some cases that may help by using Regex:

  • \W to match any character else word character [a-zA-Z0-9_]. Example:
("Hello World,I-am code").split(/\W+/); // would return [ 'Hello', 'World', 'I', 'am', 'code' ]
  • \s+ to match One or more spaces
  • \d to match a digit
  • if you want to split by some characters only let us say , and - you can use str.split(/[,-]+/)...etc

Solution 11 - Javascript

Hi for example if you have split and replace in String 07:05:45PM

var hour = time.replace("PM", "").split(":");

Result

[ '07', '05', '45' ]

Solution 12 - Javascript

I will provide a classic implementation for a such function. The code works in almost all versions of JavaScript and is somehow optimum.

  • It doesn't uses regex, which is hard to maintain
  • It doesn't uses new features of JavaScript
  • It doesn't uses multiple .split() .join() invocation which require more computer memory

Just pure code:

var text = "Create a function, that will return an array (of string), with the words inside the text";

println(getWords(text));

function getWords(text)
{
    let startWord = -1;
    let ar = [];
    
    for(let i = 0; i <= text.length; i++)
    {
        let c = i < text.length ? text[i] : " ";

        if (!isSeparator(c) && startWord < 0)
        {
            startWord = i;
        }
        
        if (isSeparator(c) && startWord >= 0)
        {
            let word = text.substring(startWord, i);
            ar.push(word);
            
            startWord = -1;
        }
    }

    return ar;
}

function isSeparator(c)
{
    var separators = [" ", "\t", "\n", "\r", ",", ";", ".", "!", "?", "(", ")"];
    return separators.includes(c);
}

You can see the code running in playground: https://codeguppy.com/code.html?IJI0E4OGnkyTZnoszAzf

Solution 13 - Javascript

Splitting URL by .com/ or .net/

url.split(/\.com\/|\.net\//)

Solution 14 - Javascript

a = "a=b,c:d"

array = ['=',',',':'];

for(i=0; i< array.length; i++){ a= a.split(array[i]).join(); }

this will return the string without a special charecter.

Solution 15 - Javascript

Here is a new way to achieving same in ES6:

function SplitByString(source, splitBy) {
  var splitter = splitBy.split('');
  splitter.push([source]); //Push initial value

  return splitter.reduceRight(function(accumulator, curValue) {
    var k = [];
    accumulator.forEach(v => k = [...k, ...v.split(curValue)]);
    return k;
  });
}

var source = "abc,def#hijk*lmn,opq#rst*uvw,xyz";
var splitBy = ",*#";
console.log(SplitByString(source, splitBy));

Please note in this function:

  • No Regex involved
  • Returns splitted value in same order as it appears in source

Result of above code would be:

enter image description here

Solution 16 - Javascript

I don't know the performance of RegEx, but here is another alternative for RegEx leverages native HashSet and works in O( max(str.length, delimeter.length) ) complexity instead:

var multiSplit = function(str,delimiter){
	if (!(delimiter instanceof Array))
		return str.split(delimiter);
	if (!delimiter || delimiter.length == 0)
		return [str];
	var hashSet = new Set(delimiter);
	if (hashSet.has(""))
		return str.split("");
	var lastIndex = 0;
	var result = [];
	for(var i = 0;i<str.length;i++){
		if (hashSet.has(str[i])){
			result.push(str.substring(lastIndex,i));
			lastIndex = i+1;
		}
	}
	result.push(str.substring(lastIndex));
	return result;
}

multiSplit('1,2,3.4.5.6 7 8 9',[',','.',' ']);
// Output: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]

multiSplit('1,2,3.4.5.6 7 8 9',' ');
// Output: ["1,2,3.4.5.6", "7", "8", "9"]

Solution 17 - Javascript

I find that one of the main reasons I need this is to split file paths on both / and \. It's a bit of a tricky regex so I'll post it here for reference:

var splitFilePath = filePath.split(/[\/\\]/);

Solution 18 - Javascript

I think it's easier if you specify what you wanna leave, instead of what you wanna remove.

As if you wanna have only English words, you can use something like this:

text.match(/[a-z'\-]+/gi);

Examples (run snippet):

var R=[/[a-z'\-]+/gi,/[a-z'\-\s]+/gi];
var s=document.getElementById('s');
for(var i=0;i<R.length;i++)
 {
  var o=document.createElement('option');
  o.innerText=R[i]+'';
  o.value=i;
  s.appendChild(o);
 }
var t=document.getElementById('t');
var r=document.getElementById('r');

s.onchange=function()
 {
  r.innerHTML='';
  var x=s.value;
  if((x>=0)&&(x<R.length))
   x=t.value.match(R[x]);
  for(i=0;i<x.length;i++)
   {
    var li=document.createElement('li');
    li.innerText=x[i];
    r.appendChild(li);
   }
 }

<textarea id="t" style="width:70%;height:12em">even, test; spider-man

But saying o'er what I have said before:
My child is yet a stranger in the world;
She hath not seen the change of fourteen years,
Let two more summers wither in their pride,
Ere we may think her ripe to be a bride.

—Shakespeare, William. The Tragedy of Romeo and Juliet</textarea>

<p><select id="s">
 <option selected>Select a regular expression</option>
 <!-- option value="1">/[a-z'\-]+/gi</option>
 <option value="2">/[a-z'\-\s]+/gi</option -->
</select></p>
 <ol id="r" style="display:block;width:auto;border:1px inner;overflow:scroll;height:8em;max-height:10em;"></ol>
</div>

Solution 19 - Javascript

Not the best way but works to Split with Multiple and Different seperators/delimiters

html

<button onclick="myFunction()">Split with Multiple and Different seperators/delimiters</button>
<p id="demo"></p>

javascript

<script>
function myFunction() {

 var str = "How : are | you doing : today?";
 var res = str.split(' | ');

 var str2 = '';
 var i;
 for (i = 0; i < res.length; i++) { 
    str2 += res[i];
    
    if (i != res.length-1) {
      str2 += ",";
    }
 }
 var res2 = str2.split(' : ');

 //you can add countless options (with or without space)

 document.getElementById("demo").innerHTML = res2;
}
</script>

Solution 20 - Javascript

I solved this with reduce and filter. It might not be the most readable solution, or the fastest, and in real life I would probably use Aarons answere here, but it was fun to write.

[' ','_','-','.',',',':','@'].reduce(
(segs, sep) => segs.reduce(
(out, seg) => out.concat(seg.split(sep)), []), 
['E-mail Address: [email protected], Phone Number: +1-800-555-0011']
).filter(x => x)

Or as a function:

function msplit(str, seps) {
  return seps.reduce((segs, sep) => segs.reduce(
    (out, seg) => out.concat(seg.split(sep)), []
  ), [str]).filter(x => x);
}

This will output:

['E','mail','Address','user','domain','com','0','Phone','Number','+1','800','555','0011']

Without the filter at the end you would get empty strings in the array where two different separators are next to each other.

Solution 21 - Javascript

I ran into this question wile looking for a replacement for the C# string.Split() function which splits a string using the characters in its argument.

In JavaScript you can do the same using map an reduce to iterate over the splitting characters and the intermediate values:

let splitters = [",", ":", ";"]; // or ",:;".split("");
let start= "a,b;c:d";
let values = splitters.reduce((old, c) => old.map(v => v.split(c)).flat(), [start]);
// values is ["a", "b", "c", "d"]

flat() is used to flatten the intermediate results so each iteration works on a list of strings without nested arrays. Each iteration applies split to all of the values in old and then returns the list of intermediate results to be split by the next value in splitters. reduce() is initialized with an array containing the initial string value.

Solution 22 - Javascript

Starting from @stephen-sweriduk solution (that was the more interesting to me!), I have slightly modified it to make more generic and reusable:

/**
 * Adapted from: http://stackoverflow.com/questions/650022/how-do-i-split-a-string-with-multiple-separators-in-javascript
*/
var StringUtils = {

  /**
   * Flatten a list of strings
   * http://rosettacode.org/wiki/Flatten_a_list
   */
  flatten : function(arr) {
    var self=this;
    return arr.reduce(function(acc, val) {
        return acc.concat(val.constructor === Array ? self.flatten(val) : val);
    },[]);
  },

  /**
   * Recursively Traverse a list and apply a function to each item
   * @param list array
   * @param expression Expression to use in func
   * @param func function of (item,expression) to apply expression to item
   *
   */
  traverseListFunc : function(list, expression, index, func) {
    var self=this;
    if(list[index]) {
        if((list.constructor !== String) && (list[index].constructor === String))
            (list[index] != func(list[index], expression)) ? list[index] = func(list[index], expression) : null;
        (list[index].constructor === Array) ? self.traverseListFunc(list[index], expression, 0, func) : null;
        (list.constructor === Array) ? self.traverseListFunc(list, expression, index+1, func) : null;
    }
  },

  /**
   * Recursively map function to string
   * @param string
   * @param expression Expression to apply to func
   * @param function of (item, expressions[i])
   */
  mapFuncToString : function(string, expressions, func) {
    var self=this;
    var list = [string];
    for(var i=0, len=expressions.length; i<len; i++) {
        self.traverseListFunc(list, expressions[i], 0, func);
    }
    return self.flatten(list);
  },

  /**
   * Split a string
   * @param splitters Array of characters to apply the split
   */
  splitString : function(string, splitters) {
    return this.mapFuncToString(string, splitters, function(item, expression) {
      return item.split(expression);
    })
  },

}

and then

var stringToSplit = "people and_other/things";
var splitList = [" ", "_", "/"];
var splittedString=StringUtils.splitString(stringToSplit, splitList);
console.log(splitList, stringToSplit, splittedString);

that gives back as the original:

[ ' ', '_', '/' ] 'people and_other/things' [ 'people', 'and', 'other', 'things' ]

Solution 23 - Javascript

>An easy way to do this is to process each character of the string with each delimiter and build an array of the splits:

splix = function ()
{
  u = [].slice.call(arguments); v = u.slice(1); u = u[0]; w = [u]; x = 0;

  for (i = 0; i < u.length; ++i)
  {
    for (j = 0; j < v.length; ++j)
    {
      if (u.slice(i, i + v[j].length) == v[j])
      {
        y = w[x].split(v[j]); w[x] = y[0]; w[++x] = y[1];
      };
    };
  };
  
  return w;
};

console.logg = function ()
{
  document.body.innerHTML += "<br>" + [].slice.call(arguments).join();
}

splix = function() {
  u = [].slice.call(arguments);
  v = u.slice(1);
  u = u[0];
  w = [u];
  x = 0;
  console.logg("Processing: <code>" + JSON.stringify(w) + "</code>");

  for (i = 0; i < u.length; ++i) {
    for (j = 0; j < v.length; ++j) {
      console.logg("Processing: <code>[\x22" + u.slice(i, i + v[j].length) + "\x22, \x22" + v[j] + "\x22]</code>");
      if (u.slice(i, i + v[j].length) == v[j]) {
        y = w[x].split(v[j]);
        w[x] = y[0];
        w[++x] = y[1];
        console.logg("Currently processed: " + JSON.stringify(w) + "\n");
      };
    };
  };

  console.logg("Return: <code>" + JSON.stringify(w) + "</code>");
};

setTimeout(function() {
  console.clear();
  splix("1.23--4", ".", "--");
}, 250);

@import url("http://fonts.googleapis.com/css?family=Roboto");

body {font: 20px Roboto;}

>Usage: splix(string, delimiters...) > >Example: splix("1.23--4", ".", "--") > >Returns: ["1", "23", "4"]

Solution 24 - Javascript

Check out my simple library on Github

If you really do not want to visit or interact with the repo, here is the working code:

/**
 * 
 * @param {type} input The string input to be split
 * @param {type} includeTokensInOutput If true, the tokens are retained in the splitted output.
 * @param {type} tokens The tokens to be employed in splitting the original string.
 * @returns {Scanner}
 */
function Scanner(input, includeTokensInOutput, tokens) {
    this.input = input;
    this.includeTokensInOutput = includeTokensInOutput;
    this.tokens = tokens;
}

Scanner.prototype.scan = function () {
    var inp = this.input;

    var parse = [];
    this.tokens.sort(function (a, b) {
        return b.length - a.length; //ASC, For Descending order use: b - a
    });
    for (var i = 0; i < inp.length; i++) {


        for (var j = 0; j < this.tokens.length; j++) {

            var token = this.tokens[j];
            var len = token.length;
            if (len > 0 && i + len <= inp.length) {
                var portion = inp.substring(i, i + len);
                if (portion === token) {
                    if (i !== 0) {//avoid empty spaces
                        parse[parse.length] = inp.substring(0, i);
                    }
                    if (this.includeTokensInOutput) {
                        parse[parse.length] = token;
                    }
                    inp = inp.substring(i + len);
                    i = -1;
                    break;
                }

            }

        }

    }
    if (inp.length > 0) {
          parse[parse.length] = inp;
    }

    return parse;


};

The usage is very straightforward:

    var tokens = new Scanner("ABC+DE-GHIJK+LMNOP", false , new Array('+','-')).scan();

console.log(tokens); 

Gives:

['ABC', 'DE', 'GHIJK', 'LMNOP']

And if you wish to include the splitting tokens (+ and -) in the output, set the false to true and voila! it still works.

The usage would now be:

var tokens = new Scanner("ABC+DE-GHIJK+LMNOP", true , new Array('+','-')).scan();

and

console.log(tokens);

would give:

['ABC', '+', 'DE', '-', 'GHIJK', '+', 'LMNOP']

ENJOY!

Solution 25 - Javascript

I use regexp:

str =  'Write a program that extracts from a given text all palindromes, e.g. "ABBA", "lamal", "exe".';

var strNew = str.match(/\w+/g);

// Output: ["Write", "a", "program", "that", "extracts", "from", "a", "given", "text", "all", "palindromes", "e", "g", "ABBA", "lamal", "exe"]

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsolView Question on Stackoverflow
Solution 1 - JavascriptAaron MaenpaaView Answer on Stackoverflow
Solution 2 - JavascriptJesse RusakView Answer on Stackoverflow
Solution 3 - JavascriptBrianView Answer on Stackoverflow
Solution 4 - JavascriptAsherView Answer on Stackoverflow
Solution 5 - Javascriptuser669677View Answer on Stackoverflow
Solution 6 - JavascriptStephen SweridukView Answer on Stackoverflow
Solution 7 - JavascriptblockchainwtfView Answer on Stackoverflow
Solution 8 - JavascriptPeterKAView Answer on Stackoverflow
Solution 9 - JavascriptJanuszOView Answer on Stackoverflow
Solution 10 - JavascriptAhmad AlsabbaghView Answer on Stackoverflow
Solution 11 - JavascriptEzequiel GarcíaView Answer on Stackoverflow
Solution 12 - JavascriptcodeguppyView Answer on Stackoverflow
Solution 13 - JavascriptImranView Answer on Stackoverflow
Solution 14 - Javascriptgaurav krishnaView Answer on Stackoverflow
Solution 15 - JavascriptVishnuView Answer on Stackoverflow
Solution 16 - JavascriptOrhun Alp OralView Answer on Stackoverflow
Solution 17 - JavascriptAlliterativeAliceView Answer on Stackoverflow
Solution 18 - JavascriptESLView Answer on Stackoverflow
Solution 19 - JavascriptStavrosView Answer on Stackoverflow
Solution 20 - Javascriptkaan_aView Answer on Stackoverflow
Solution 21 - JavascriptDonald RichView Answer on Stackoverflow
Solution 22 - JavascriptloretoparisiView Answer on Stackoverflow
Solution 23 - Javascriptharr-willView Answer on Stackoverflow
Solution 24 - JavascriptgbenroscienceView Answer on Stackoverflow
Solution 25 - JavascriptDodi IvanovView Answer on Stackoverflow