Decompose string into blocks

Retina, 31 bytes

S-_` (?=([^)]|(\()|(?<-2>.))+$)

Try it online!

This is a standard exercise in balancing groups. We simply match all spaces from which we can reach the end of the string while passing only correctly matched parentheses (since the ones we don't want to remove are followed by an unmatched closing parenthesis), and split the input around those matches. The _ option removes empty segments in case there are several spaces in a row and the - suppresses the default behaviour to include captured substrings in the result.

Retina, 30 bytes


1 byte shorter...

Try it here.

MATL, 22 bytes


Try it online!


This uses a builtin function for splitting a string at spaces. To avoid splitting at spaces between matching parentheses, these are first detected and replaced by character 0. This is not detected as a space by the string-splitting function, but is treated as a space by the implicit display function.

j        % Take input as a string. 
0        % Push 0
G40=     % True for occurrences of '(' 
G41=     % True for occurrences of ')' 
-Ys      % Subtract and cumulative sum. Positive values correspond to characters
         % between matching parentheses
G32=     % True for occurrences of space
*g       % Multiply, convert to logical. Gives true for spaces between matching
         % parentheses
(        % Assign 0 to those positions. This replaces spaces between matching
         % parentheses by character 0
Yb       % Split at spaces, treating consecutive spaces as a single space.
         % Character 0 does not cause splitting, but is displayed as a space