match all parentheses between two curly brackets

Viewed 106

I'm trying to find a RegEx pattern that lets me match on all parentheses (and their content) as long as these parentheses are between { and }.

Examples:

  • {foo (i,j) bar} should match on (i,j)
  • {(i,j) foo (k,l) bar (m,n,o)} should match on (i,j), (k,l), and (m,n,o).
  • foo (i,j) bar should not match on anything because the string is not between swirly brackets.
  • {foo (i,j) bar} (k,l) should match on (i,j) but not (k,l) because the latter is outside of the swirly brackets.

The closest I came was with this pattern: (?<=\{)[^\(].*\(.*?\).*(?=\}). This pattern matched on the first, second, and fourth example, but matched on all of the content between the swirly brackets instead of only the parentheses and their content.

1 Answers

You can use

(?:\G(?!\A)|{)[^{}]*?\K\([^()]*\)

See the regex demo. If you want to make absolutely sure there is a closing } on the right, add a (?=[^{}]*}) positive lookahead at the end:

(?:\G(?!\A)|{)[^{}]*?\K\([^()]*\)(?=[^{}]*})

See this regex demo.

Details

  • (?:\G(?!\A)|{) - either end of the previous successful match or a { char
  • [^{}]*? - zero or more chars other than { and }, as few as possible
  • \K - match reset operator that discards all text matched so far from the current overall match memory buffer
  • \( - a ( char
  • [^()]* - zero or more chars other than ( and ) as many as possible
  • \) - a ) char
  • (?=[^{}]*}) - immediately on the right, there must be zero or more chars other than { and } and then a }.

See an R demo online:

x <- "{(i,j) foo (k,l) bar (m,n,o)} should match on (h,j), (a,s), and (i,o,g)."
regmatches(x, gregexpr("(?:\\G(?!\\A)|{)[^{}]*?\\K\\([^()]*\\)(?=[^{}]*})", x, perl=TRUE))
# [[1]]
# [1] "(i,j)"   "(k,l)"   "(m,n,o)"
Related