1

i just want to make

str = "a(bcde(dw)d)e"

to

arr = {"a", "(bcde)", "(dw)", "(d)", "e"}

What regEx can i use in str.split()?

PS: Explanations || helpful links welcome.

Examples:

s: "a(bcdefghijkl(mno)p)q" --> [ 'a', '(bcdefghijkl)', '(mno)', '(p)', 'q' ]
s: "abc(cba)ab(bac)c" --> [ 'abc', '(cba)', 'ab', '(bac)', 'c' ]
5
  • 2
    your result looks a bit strange || invalid. Commented Apr 21, 2017 at 7:59
  • 4
    Is the result supposed to be an array of strings, ["a", "(bcde)", "(dw)", "(d)", "e"]? Commented Apr 21, 2017 at 8:01
  • Yes, it is supposed to be an array of strings. Commented Apr 21, 2017 at 8:04
  • Can you add a few edge cases? What about "a(b)c(d)e"? What about "(a(b)c(d)e)"? Commented Apr 21, 2017 at 8:39
  • What about "(a(b(c)))d(e)"? Commented Apr 21, 2017 at 8:47

4 Answers 4

4

Go through each parentheses using a counter:

array = [], c = 0;

'abc(cba)ab(bac)c'.split(/([()])/).filter(Boolean).forEach(e =>
// Increase / decrease counter and push desired values to an array
e == '(' ? c++ : e == ')' ? c-- : c > 0 ? array.push('(' + e + ')') : array.push(e)
);

console.log(array)

Sign up to request clarification or add additional context in comments.

1 Comment

Note: This is ES6 syntax and will not work as is in older browsers
3

Edit

str = "a(bcde(dw)d)e"
    // replace any `(alpha(` by `(alpha)(`
    str1 = str.replace(/\(([^)]+)\(/g, '($1)(');
    // replace any `)alpha)` by )(alpha)`
    str2 = str1.replace(/\)([^(]+)\)/g, ')($1)');
    // prefix any opening parenthesis with #--# (just a character string unlikly to appear in the original string)
    str3 = str2.replace(/\(/g, '#--#(');
    // prefix any closing parenthesis with  #--#
    str4 = str3.replace(/\)/g, ')#--#');
    // remove any double `#--#`
    str5 = str4.replace(/(#--#)+/g, '#--#');
    // split by invented character string
    arr = str5.split('#--#');
    console.log(arr);

Old wrong answer

    str = "a(bcde(dw)d)e"
    console.log(str.split(/[()]/));

This looks a little bit weird, but it's like this.

str is string which has a split method. This can take a string or a regular expression as argument. A string will be delimited by " and a RegExp by /. The brackets [] wrap a character class which means any one of the characters inside. Then inside we have the two parentheses () which are the two characters we are looking for.

1 Comment

The result of this answer is [a,bcde,dw,d,e]. Not exactly what the OP was looking for...
1

I don't think the result you want is possible without modifying the values of the array after the split. But if you want to be able to split the string based on 2 symbols (in this case the brackets '(' and ')') you can do this:

var arr = str.split("(").toString().split(")");

It returns an array with the "words" of the string.

I hope I could help.

1 Comment

Suggest using str.split("{").join('').split(")") to avoid additional comma created by toString()
0

Given that the desired output includes characters that aren't in the string, e.g., adding closing or opening parentheses to the substrings in the outer part of the nested parentheses, it will be necessary to make some changes to the individual substrings after they are extracted one way or another.

Maybe something like this:

function getGroups(str) {
  var groups = str.match(/(?:^|[()])[^()]+/g)
  if (!groups) return []
  var parenLevel = 0
  return groups.map(function(v) {
    if (v[0] === "(") {
      parenLevel++
    } else if (v[0] === ")") {
      parenLevel--
    }
    v = v.replace(/[()]/,"")
    return parenLevel > 0 ? "(" + v + ")" : v
  })
}

console.log(JSON.stringify( getGroups("a(bcde(dw)d)e") ))
console.log(JSON.stringify( getGroups("abc(cba)ab(bac)c") ))
console.log(JSON.stringify( getGroups("ab(cd)ef(gh)") ))
console.log(JSON.stringify( getGroups("ab(cd)(e(f(gh)i))") ))
console.log(JSON.stringify( getGroups("(ab(c(d))ef(gh)i)") ))

2 Comments

for str: "abc(cba)ab(bac)c" it gives me [ 'abc', '(cba)', '(ab)', '(bac)', 'c' ].
Ah. OK, I've whipped up something a little different (see my edit). I don't have time to test it properly, but it seems OK for the few cases I tried.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.