4

I want to split a string based on multiple delimiters.

How to split a string with multiple strings as separator?

For example:

I have a string: "/create #channel 'name' 'description of the channel' #field1 #field2"

And I want an array with:

/create
#channel
name
description of the channel
#field1
#field2

Another example, i have: "/send @user 'A messsage'" And I want:

/send
@user
A message

How to solve it? Any help, please? :-(

Eusthace
  • 3,601
  • 7
  • 34
  • 41
  • here's a possible solution: create a for loop starting from 0 to the length of the string - 1 to make a temporary array that contains the INDICES of every char that has a delimiter that you care about. (@, /, ', etc...) Then use another for loop to make a new array with substrings of the initial string with parameters based on the indices from this temp array you created. Hope this helps. – Kabir Peshawaria Sep 24 '15 at 05:52
  • i posted a jsfiddle in my answer that does it with regex, but i would say that parsing it like in @ShailendraSharma 's answer is probably better and more secure – x4rf41 Sep 24 '15 at 05:59
  • How about splitting the string by space and replacing the removing the occurrence of `'` from every item of the split result array. – Gaurav Gupta Sep 24 '15 at 06:11
  • @GauravGupta That wont work for strings like `'description of the channel'` – Tushar Sep 24 '15 at 06:13
  • @Tushar That's right. I missed that totally. – Gaurav Gupta Sep 24 '15 at 06:14
  • possible duplicate of [Split a string by whitespace, keeping quoted segments, allowing escaped quotes](http://stackoverflow.com/questions/4031900/split-a-string-by-whitespace-keeping-quoted-segments-allowing-escaped-quotes) – Mariano Sep 24 '15 at 07:20

5 Answers5

3

here the solution without Regx

var multiSplit = function (str, delimeters) {
    var result = [str];
    if (typeof (delimeters) == 'string')
        delimeters = [delimeters];
    while (delimeters.length > 0) {
        for (var i = 0; i < result.length; i++) {
            var tempSplit = result[i].split(delimeters[0]);
            result = result.slice(0, i).concat(tempSplit).concat(result.slice(i + 1));
        }
        delimeters.shift();
    }
    return result;
}

simply use

multiSplit("/create #channel 'name' 'description of the channel' #field1 #field2",['/','#','@',"'"])

output

Array [ "", "create ", "channel ", "name", " ", "description of the channel", " ", "field1 ", "field2" ]
Tushar
  • 85,780
  • 21
  • 159
  • 179
Shailendra Sharma
  • 6,976
  • 2
  • 28
  • 48
2

You can use regex

/([\/#]\w+|'[\s\w]+')/g

For regex explanation: https://regex101.com/r/lE4rJ7/3

  1. [\/#@]\w+: This will match the strings that start with #, / or @
  2. |: OR condition
  3. '[\s\w]+': Matches the strings that are wrapped in quotes

As the regex will also match the quotes, they need to be removed.

var regex = /([\/#@]\w+|'[\s\w]+')/g;

function splitString(str) {
  return str.match(regex).join().replace(/'/g, '').split(',');
}

var str1 = "/create #channel 'name' 'description of the channel' #field1 #field2 @Tushar";
var str2 = "/send @user 'A messsage'";

var res1 = splitString(str1);
var res2 = splitString(str2);

console.log(res1);
console.log(res2);

document.write(res1);
document.write('<br /><br />' + res2);
Tushar
  • 85,780
  • 21
  • 159
  • 179
0

this one works for your case, but not with split:

('[^']+'|[^\s']+)

note: you will still have to trim the single-quotes!

here is an example: http://jsfiddle.net/k8s8r77e/1/

but i can't tell you if it will always work. Parsing in that way is not really what regex is for.

x4rf41
  • 5,184
  • 2
  • 22
  • 33
0

Something like this might work.. but would have to be tweaked to not wipe out apostrophes

var w = "/create #channel 'name' 'description of the channel' #field1 #field2";

var ar = w.split();

ar.forEach(function(e, i){  
    e = e.replace(/'/g, '')
    console.log(e)
})

fiddle: http://jsfiddle.net/d9m9o6ao/

Steve
  • 1,326
  • 14
  • 21
0

There is something inconsistent in the example you gave, you either split by those fields or give them as fields markers, but you seem to mix. Take you first example, in the original string you have 'name', but in the result you strip it of the ' and have only name, while #channel keeps the #. Anyways you have 2 options:

String.split takes a regular expression so you can use:

var re = /['\/@#"]+\s*['\/@#"]*/;

var str = "/create #channel 'name' 'description of the channel' #field1 #field2";
var parts = str.split(re);

You get an array of your tokens. Note the first one in this case is empty, just remove empty strings before using the parts array.

Or, use string.match with a regexp:

var re = /['\/@#"][^'\/@#"]*/g;
var parts = str.match(re);
Meir
  • 14,081
  • 4
  • 39
  • 47