Bash can natively match regular expressions in the [[ ]] construct, using the =~ operator. When it matches something, the result is stored in the BASH_REMATCH array variable. BASH_REMATCH contains, in order, the entire matched text, and then each matched subexpression:$ foo=abcd$ [[ $foo =~ (.(.))(.) ]]$ printf %s\n ${BASH_REMATCH[@]}abcabbcIs there something that would look like:let foo = 'abcd'let bar = groupmatch(foo, '\(.\(.\)\)\(.\)')And echo bar would give:['abc', 'ab', 'b', 'c']It would be something like split(), but far, far more powerful. The (.(.))(.) is just a toy expression - the full power of regular expressions can be availed in [[ ]].
Is there a function which can return a list of matching text for groups in a regex?
vimscript;regular expression
Maybe you could try matchlist() and filter(), like this::let foo = 'abcd':let bar = filter(matchlist(foo, '\v(.(.))(.)'), 'v:val !=# ')The output of :echo bar should be:['abc', 'ab', 'b', 'c']matchlist() by itself always returns a list of ten items if the match was successful, one for each possible sub-expression, whether or not the pattern actually contained enough sub-expressions::echo matchlist('abcd', '\v(.(.))(.)')['abc', 'ab', 'b', 'c', '', '', '', '', '', '']More than nine sub-expressions causes it to error out::echo matchlist('abcdefghijklmn', '\v(.(.))(.(.))(.(.))(.(.))(.(.))(.(.))')E872: (NFA regexp) Too many '('E51: Too many ([]Whereas Bash can go further:$ foo=abcdefghijklmn$ [[ $foo =~ (.(.))(.(.))(.(.))(.(.))(.(.))(.(.)) ]]$ printf %s\n ${#BASH_REMATCH[@]} ${BASH_REMATCH[@]}13abcdefghijklabbcddeffghhijjkll