Denis Kulagin
Denis Kulagin

Reputation: 8906

Extract parts from bracketed string

There is a string some parts of which are marked w/brackets:

abc(de)f(uv)xyz

How to split it into parts like:

abc | false
de | true
f | false
uv | true
xyz | false

Where true stands for a bracketed part and false stands for an unbracketed one.

N.B. Brackets are only used for marking purpose. Nested, unpaired brackets and other complex scenarious are not possible.

Upvotes: 0

Views: 49

Answers (1)

AndreasPizsa
AndreasPizsa

Reputation: 1746

The Regular Expression

Given that the bracket sequence is guaranteed to be valid and not to contain nested sequences, we can keep the regular expression quite simple:

\(?([^()]+)\)?

  1. \(? - optionally accept an opening bracket
  2. ([^()]+)- capture anything that’s not an opening or closing bracket
  3. \)? - optionally accept a closing bracket

The Code

Executing the Regular Expression

Once we execute the regex (execAll(pattern, text)) we get

const matches = execAll(pattern, text)

[
  ['abc', 'abc'],
  ['(de)', 'de'],
  ['f'   , 'f' ]
  ['(uv)', 'uv'],
  ['xyz', 'xyz']
]

Bracketed vs unbracketed

Index 0 of each entry is the matched text and index 1 is the captured group.

Looking at the first character of index 0 tells us whether it’s a group or not:

matches[0][0] === '(' // false
matches[1][0] === '(' // true

Bringing it in the right order

We want the text first and the boolean second:

matches.map(([bracket, group]) => [group, bracket[0]==='('])

[
  ['abc', false],
  ['de' , true ],
  ['f'  , false]
  ['uv' , true ],
  ['xyz', false]
]

Done!

Solution

const execAll = (pattern, str) => {
    const result=[]
    let match
    while((match = pattern.exec(str))) {
        result.push(match)
    }
    return result
}

const extractGroups = text => {
  const pattern = /\(?([^()]+)\)?/g
  const matches = execAll(pattern, text)
  return matches
    .map(([bracket, group]) => [group, bracket[0]==='('])
}
  
console.log(extractGroups('abc(de)f(uv)xyz'))

Upvotes: 1

Related Questions