the view.replace API is decoupled from the view.find_all API, in that replace knows nothing about any capture groups as it is designed to be used standalone, not just as a result of regex matches.
view.find_all doesn’t expose the capture groups that matched directly, or their positions, but it’s possible to use the format string with $1 etc. to get the text that was captured, though if you have multiple capture groups, you’ll probably want to parse the extractions afterwards.
e.g.
extractions = list()
regions = view.find_all(r'(\w+), (\w+)', 0, '$1\n$2', extractions)
capture_group_contents = [extraction.split('\n') for extraction in extractions]
ofc there are other possible solutions to get the capture group locations, including executing the regex searches multiple times with lookaheads and \K in the relevant places, or using Python’s more limited built-in re module.
btw the docs don’t mention that the format string should be in Perl format and not Boost Extended format