You can use a block, then the global variables $1
.. $9
hold matches. This achieves what you want:
map = { 'stack' => 'overflow' }
p "stackoverflow".gsub(/(stack)(overflow)/) { map[$1] + $2 }
# => overflowoverflow
Alternatively, you can just pass a variable to the block:
map = { 'stack' => 'overflow' }
p "stackoverflow".gsub(/stack/) { |match| map[match] }
# => overflowoverflow
See String#gsub for reference.