3

Actually I need to split this line by whitespaces ignoring those in parentheses (could be nested):

var string = 'a b c(a b c) d(a (b) c)'

Into this array:

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

The essence of my task is to get list of all variables and function calls separated by whitespaces

So, splitting by whitespaces, everything in parentheses should be ignored

I understand how it is godless to ask such questions, but I am totally dumb when it comes to regexps and, if that, ready to wait to start a bounty) Thx)

Maybe it should be something like this:

string = 'a b c(a b c) d(a (b) c)'.relaceWhitespacesinParentheses('&wh;')

// 'a b c(a&wh;b&wh;c) d(a&wh;(b)&wh;c)'

string.split(' ')

// ['a', 'b', 'c(a&wh;b&wh;c)', 'd(a&wh;(b)&wh;c)']

Everything next is obvious

MaxCore
  • 2,438
  • 4
  • 25
  • 43

3 Answers3

4

var str = 'a b d(a (b) c) c(a b c)   e(a (f t(o a i) ) ) ';
str = str.trim();
var result = [];
var open_bracket = 0;
var curr_str = '';

for (var i = 0; i < str.length; ++i) {
  if (str.charAt(i) === '(') open_bracket++;
  if (str.charAt(i) === ')') open_bracket--;

  if (str.charAt(i) == ' ') {
    if (open_bracket == 0 && curr_str != '') {
      result.push(curr_str);
      curr_str = '';
    } else if (open_bracket > 0) {
      curr_str += str.charAt(i);
    }
  } else {
    curr_str += str.charAt(i);
  }
}

result.push(curr_str); // to include the last matched token.
console.log(result);

We move inside the string character by character. When we find a space, we see if we need to accommodate it in out result by checking if we have any brackets open. If yes, we append it to our temp result curr_str, else, we add the current curr_str to our results.

nice_dev
  • 17,053
  • 2
  • 21
  • 35
  • 2
    You are the hero! One problem I have now: @bobble bubble provided also a correct answer. But, honestly I simplified question, and there are really infinitive parentheses in my task. So I will use your solution. So, if his comment will get at least two upvotes, I'll remark your answer as correct – MaxCore Jun 10 '19 at 16:00
3

Maybe something like this? There's probably a tidier way

var string = 'a b c(a b c) d(a (b (a b c) d) c)'
var split = string.split(' ')

var numberOfBrackets = 0
var elements = []
split.reduce(function (acc, cur) {
  if (cur.includes('(')) {numberOfBrackets++}
  if (cur.includes(')')) {numberOfBrackets--}
  if (numberOfBrackets !== 0) {
    return acc + ' ' + cur
  } else {
    elements.push((acc + ' ' + cur).trim())
  }
  return ''
}, '')

console.log(elements)
dbramwell
  • 1,298
  • 6
  • 11
  • I've tested this, unfortunately could not deal with 3 level parentheses `var string = 'a b c(a b c) d(a ((b) (c)))';` @vivek_23 solution can with infinitive – MaxCore Jun 10 '19 at 16:30
2

If there is max one level of nesting you could try this pattern.

var str = 'a b c(a b c) d(a (b) c)';

var res = str.match(/\w+\([^)(]*(?:\([^)(]*\)[^)(]*)*\)|\S+/g);

console.log(res);

You'd need to add each level of deeper nesting to the pattern. Eg with max two levels (fyi).

bobble bubble
  • 16,888
  • 3
  • 27
  • 46
  • There is no way to specify infinitive nesting using regexp, right? I have a problem, your answer perfectly solves current question. But there are answers below without RegExp but covering infinitive nesting (actually my real life task has function call in function call). So can I ask you and community - is it ok if I mark them as accepted? – MaxCore Jun 10 '19 at 16:08
  • Another interesting thing) What would you do in my shoes?) Go learn `matchRecursive` or stay with some solutions below?) – MaxCore Jun 10 '19 at 16:12
  • 1
    @MaxCore I'm not here for reputation but for learning. Don't bother, just pick the answer that fits your task best :) I knew my answer only works for finite levels of nesting. – bobble bubble Jun 10 '19 at 16:16
  • Should I forget about `matchRecursive` in this current task?) – MaxCore Jun 10 '19 at 16:18
  • 1
    The other people spent probably more time and effort writing that answers. Play with the API if you're interested, it's certainly useful for other tasks as well. – bobble bubble Jun 10 '19 at 16:23