'Escaping back-references in recursive search

Is it possible to back-reference the result of an outer :g command in a recursive call (or an inner :s call?)

For instance, let's say I want to search for something above the cursor, and modify it when it appears below the cursor:

:1,.g/Hello, \(\w\+\)!/.,$s/\1/\1-San

This should replace:

Hello, Luciano!

Goodbye, Luciano!

with

Hello, Luciano!

Goodbye, Luciano-San!

If you place the cursor on the empty line.

However, it complains about an invalid back-reference. This is in reference to the last \1 (note that , maybe surprisingly the first \1 in the search pattern -but not the replacement - works!). The reason is likely that the :s expression does not have any capture groups.

So my question is, whether there is a way to 'escape' the inner context of the command to execute in :g to be able to back-reference a match group from the outer g?

(I appreciate there are other ways to achieve the desired effect in the above contrived example - but my question relates specifically to escaping back references, not writing a better regex - the example here is just for illustration)



Solution 1:[1]

Back references can be used within a search pattern:

before: xoxoxo foobarfoo xoxoxo

/\(foo\)bar\1

after: xoxoxo foobarfoo xoxoxo
              ^^^^^^^^^

as well as in the replacement part of a substitution:

before: xoxoxo foobarfoo xoxoxo

:s/\(foo\)bar\1/baz\1baz

after: xoxoxo bazfoobaz xoxoxo

This is possible because the capture group and the back reference occupy the same "pattern space" in a single atomic "command".

When you do :g/<pattern>/<cmd>, <cmd> is a separate "command" that doesn't share :g's "pattern space" so it is impossible to reference a capture group from <pattern> in <cmd>.

What is possible, though, is to reuse <pattern> in <cmd>:

:g/\(foo\)bar\1/s//baz\1baz

but you are still not referencing a capture group from :g in :s even if it looks like it. You are making a new search with the same pattern and referencing the capture group in that new search.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 romainl