vim 在递归搜索中转义反向引用

jslywgbw  于 2022-11-11  发布在  其他
关注(0)|答案(1)|浏览(151)

是否可以在递归调用(或内部:s调用)中反向引用外部:g命令的结果?
例如,假设我想搜索光标上方的内容,并在它出现在光标下方时对其进行修改:

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

这应取代:

Hello, Luciano!

Goodbye, Luciano!

Hello, Luciano!

Goodbye, Luciano-San!

如果将光标放在空行上。
但是,它会抱怨反向参照无效。这是指最后一个\1(请注意,搜寻样式中的第一个\1(但不是取代项)可能会发生作用!)。原因可能是:s表示式没有任何撷取群组。
所以我的问题是,是否有一种方法可以“转义”要在:g中执行的命令的内部上下文,以便能够从外部g中back-reference匹配组?
(我知道还有其他方法可以在上面的人造例子中达到预期的效果--但是我的问题特别涉及到转义返回引用,而不是编写一个更好的正则表达式--这里的例子只是为了说明)

5kgi1eie

5kgi1eie1#

可以在搜索模式中使用反向引用:

before: xoxoxo foobarfoo xoxoxo

/\(foo\)bar\1

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

以及替换的替换部分:

before: xoxoxo foobarfoo xoxoxo

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

after: xoxoxo bazfoobaz xoxoxo

这是可能的,因为捕获组和后向参考在单个原子“命令”中占据相同的“模式空间”。
当您执行:g/<pattern>/<cmd>时,<cmd>是一个单独的“命令”,它不共享:g的“模式空间”,因此不可能在<cmd>中引用来自<pattern>的捕获组。
但是,可以在<cmd>中重用<pattern>

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

但您仍未在:s中引用来自:g的捕获组,即使它看起来像捕获组。您正在使用相同的模式进行新的搜索,并在该新搜索中引用捕获组。

相关问题