lviggiani
lviggiani

Reputation: 6066

Regex split string by spaces taking into account nested brackets

I know that this has been asked/answered several times but unfortunately none of the solutions I've tried so far works in my case. I need to split something like this:

contrast(200%) drop-shadow(rgba(0, 0, 0, 0.5) 0px 0px 10px)

into this:

contrast(200%)
drop-shadow(0px 0px 10px rgba(0,0,0,.5))

By following this solution, I'm currently doing this:

myString = "contrast(200%) drop-shadow(rgba(0, 0, 0, 0.5) 0px 0px 10px)"
myString.match(/[^\(\s]+(\(.*?\)+)?/g)

but this gives me:

contrast(200%)
drop-shadow(rgba(0, 0, 0, 0.5)  <== notice the missing second ) here
0px    <== unwanted, should go with previous one
0px    <== unwanted, should go with previous one
10px)  <== unwanted, should go with previous one

as the regexp does not capture all closing brackets...

Upvotes: 0

Views: 178

Answers (2)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626758

You may split a string on spaces/tabs that are outside of nested parentheses using the code below:

function splitOnWhitespaceOutsideBalancedParens() {
  var item = '', result = [], stack = 0, whitespace = /\s/;
  for (var i=0; i < text.length; i++) {
    if ( text[i].match(whitespace) && stack == 0 ) {
        result.push(item);
        item = '';
        continue;
    } else if ( text[i] == '(' ) {
        stack++;
    } else if ( text[i] == ')' ) {
        stack--;
    }
    item += text[i];
  }
  result.push(item);
  return result;
}

var text = "contrast(200%) drop-shadow(rgba(0, 0, 0, 0.5) 0px 0px 10px)";
console.log(splitOnWhitespaceOutsideBalancedParens(text));

Upvotes: 1

lviggiani
lviggiani

Reputation: 6066

Here is my solution:

function splitBySpaces(string){
    var openBrackets = 0, ret = [], i = 0;
    while (i < string.length){
        if (string.charAt(i) == '(')
            openBrackets++;
        else if (string.charAt(i) == ')')
            openBrackets--;
        else if (string.charAt(i) == " " && openBrackets == 0){
            ret.push(string.substr(0, i));
            string = string.substr(i + 1);
            i = -1;
        }
        i++;
    }

    if (string != "") ret.push(string);
    return ret;
}

Upvotes: 2

Related Questions