$re = '/\${(fn\.[a-zA-Z0-9\/._-]+)\( *((?:[a-zA-Z0-9\/._${}=, \"\'\[\]-]|(?R))*?) *\)}/m';
$str = '${fn.abaco()}
${fn.abaco(1)}
${fn.abaco(2, 3)}
${fn.abaco(2, 3)}
${fn.abaco(${config.a})}
${fn.abaco${config.t}(2, )}
${fn.abaco(2, )}
anwkdfb a ${fn.abaco(${config.a})} ${fn.aba${fn.abaco(${config.a})}co(${config.a})} akwhcb kbkw bhj
${fn.abaco(${config.a}, ${fn.a()})}
${fn.abaco(${config.a}, ${fn.a}, [1, 2, 3])}
${fn.aba${fn.abaco(${config.a})}co}
${fn.aba${fn.abaco(${fn.a(})}co}
${fn.identity( ${fn.identity(${fn.identity(${fn.identity(${foo})})})} )}
${fn.and( True, True )}
${fn.and( ${config.first_part}, ${config.second_part} )}
${fn.map( ${config.arg}, ${fn.lambda([x], ${fn.sum(${L.x}, 1)})} )}
${fn.map( elem=${config.arg}, map_fn=${fn.lambda([x], ${fn.sum(${L.x}, 1)})} )}';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
// Print the entire match result
var_dump($matches);
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for PHP, please visit: http://php.net/manual/en/ref.pcre.php