3

can any body tell me to split a string in java script with space which is not within single quote.

Like if string is

"0 60 120 180 'node name' 2 34 45 12"

then it will tokenize such that

arr[0]=0
arr[1]=60
arr[2]=120
arr[3]=180
arr[4]='node name'
arr[5]=2
arr[6]=34
arr[7]=45
arr[8]=12

During split if single quotes remove then also good as this is the legend name in chart and I have to fetch that name in single element

Cœur
  • 37,241
  • 25
  • 195
  • 267
agarwal_achhnera
  • 2,582
  • 9
  • 55
  • 84
  • Is there a way to escape single quotes which needs to be handled? – Bergi Jun 05 '13 at 09:38
  • use this regex .. "([^"]*)" – Rinku Jun 05 '13 at 09:39
  • oldest duplicate I've [found here](http://stackoverflow.com/search?q=javascript+split+string+space+quote): [parsings strings: extracting words and phrases](http://stackoverflow.com/questions/64904/parsings-strings-extracting-words-and-phrases-javascript). Another notable one: http://stackoverflow.com/q/2817646 – Bergi Jun 05 '13 at 09:46

5 Answers5

5

This regex will do it:

var arr = string.match(/'[^']*'|[^ ]+/g) || [];
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
3

You can do this :

var s = "0 60 120 180 'node name' 2 34 45 12";
var arr = [];
s.split("'").forEach(function(v,i){
    arr = arr.concat(i%2 ? v : v.trim().split(' '))
});

It also removes the single quotes :

["0", "60", "120", "180", "node name", "2", "34", "45", "12"] 

Demonstration

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
0

If you don't have nested quotes, this will work. First I searched for any single quote in the string, then splitting by space:

var s = "0 60 120 180 'node name' 2 34 45 12";
var a = s.split("'");
var r = [];
for (var i = 0, l = a.length; i <l; i++) {
    if (i % 2) {
        r.push("'" + a[i] + "'");
    }
    else {
        var x = a[i].split(' ');
        for (var j = 0, k = x.length; j < k; j++) {
            if (x[j] != '') {
                r.push(x[j]);
            }
        }
    }
}

console.log(r);
// ["0", "60", "120", "180", "'node name'", "2", "34", "45", "12"]
  • I'm a bit sketchy with the `%` Modulus operator. Does your if statement `if(i%2)` read - if(i\2) is truthy (has a remainder) do something else (if it's falsy) do something else (if it divides exactly) – Mark Walters Jun 05 '13 at 09:52
  • @MarkWalters correct: `if(i%2)` means `if(i is not divisible by 2)` – John Dvorak Jun 05 '13 at 10:02
  • @JanDvorak Aha, thanking you. In essence using `%2` will return true for all odd numbers? – Mark Walters Jun 05 '13 at 10:06
  • @MarkWalters in essence, yes. More correctly, it returns `1` or `0` (which are truthy and falsy, respectively). – John Dvorak Jun 05 '13 at 10:12
0

Think I might be a bit late and it is a bit verbose, but it's one easy to understand and general solution. Works for all delimiters and 'join' characters. Also supports 'joined' words that are more than two words in length.... ie lists like "hello my name is 'jon delaware smith fred' I have a 'long name'"....

On @Bergi's advise I have made it a little less verbose...

function split(input, delimiter, joiner){
    var output = [];
    var joint = [];
    input.split(delimiter).forEach(function(element){
        if (joint.length > 0 && element.indexOf(joiner) === element.length - 1)
        {
            output.push(joint.join(delimiter) + delimiter + element);
            joint = [];
        }
        if (joint.length > 0 || element.indexOf(joiner) === 0)
        {
            joint.push(element);
        }
        if (joint.length === 0 && element.indexOf(joiner) !== element.length - 1)
        {
            output.push(element);
            joint = [];
        }
    });
    return output;
  }
tigerswithguitars
  • 2,497
  • 1
  • 31
  • 53
  • 1
    "bit verbose" is quite an understatement :-) It would be better to understand if you did use some of the standard array methods. – Bergi Jun 05 '13 at 10:29
  • I've only used split, length and push..... then indexof for strings. There are 2 arrays and 3 ifs though, lol. I'm not saying there's not a lot of code. I guess if I'd used more of the built in stuff like concat and forEach.... I might edit it if I get a minute. – tigerswithguitars Jun 05 '13 at 10:48
0

ES6 solution supporting:

  • Split by space except for inside quotes
  • Removing quotes but not for backslash escaped quotes
  • Escaped quote become quote
  • Can put quotes anywhere

Code:

string.match(/\\?.|^$/g).reduce((p, c) => {
        if(c === "'"){
            p.quote ^= 1;
        }else if(!p.quote && c === ' '){
            p.a.push('');
        }else{
            p.a[p.a.length-1] += c.replace(/\\(.)/,"$1");
        }
        return  p;
    }, {a: ['']}).a

Output:

[ '0', '60', '120', '180', 'node name', '2', '34', '45', '12' ]
Tsuneo Yoshioka
  • 7,504
  • 4
  • 36
  • 32