我看到了其他关于查找第 n 次出现的单词/模式的问题,但我找不到你将如何实际替换 vim 中第 n 次出现的模式。有一种明显的硬编码所有事件的方法,比如
:s/.*\(word\).*\(word\).*\(word\).*/.*\1.*\2.*newWord.*/g
有没有更好的方法来做到这一点?
我看到了其他关于查找第 n 次出现的单词/模式的问题,但我找不到你将如何实际替换 vim 中第 n 次出现的模式。有一种明显的硬编码所有事件的方法,比如
:s/.*\(word\).*\(word\).*\(word\).*/.*\1.*\2.*newWord.*/g
有没有更好的方法来做到这一点?
有关信息,
s/\%(\(pattern\).\{-}\)\{41}\zs\1/2/
也可以替换第 42 次出现。但是,我更喜欢John Kugelman 给出的更简单的解决方案——即使它不会将自身限制在当前行。
您可以通过使用多个搜索更简单地做到这一点。命令中的空模式:s/pattern/repl/
表示替换最近的搜索结果。
:/word//word//word/ s//newWord/
or
:/word//word/ s/word/newWord/
然后,您可以通过执行多次重复此命令@:
,甚至10@:
可以再重复该命令 10 次。
或者,如果我以交互方式执行此操作,我会执行以下操作:
3/word
:s//newWord/r
这将找到从光标开始的第三次出现的单词,然后执行替换。
用 REPLACE替换每行中第 N次出现的 PATTERN。
:%s/\(\zsPATTERN.\{-}\)\{N}/REPLACE/
为了替换 vim 中一行中第 n 次出现的 PATTERN,除了上面的答案之外,我只想解释模式匹配,即它实际上是如何工作的,以便于理解。
所以我将讨论
\(.\{-}\zsPATTERN\)\{N}
解决方案,
我将使用的示例是替换一个 sentence(string) 中第二次出现的超过 1 个空格。根据模式匹配码->
根据zs doc,
\zs
- 水平滚动文本以将光标定位在屏幕的开头(左侧)。
.\{-}
0 或更多尽可能少 (*)
这里 。匹配任何字符和 {} 的次数。例如 ab{2,3}c 这里它将匹配 b 出现 2 次或 3 次的位置。
在这种情况下,我们也可以使用.*
which is 0 或尽可能多的。根据 vim non-greedy docs,“{-}”与“*”相同,但使用最短匹配优先算法。
\{N}
-> 匹配前一个原子的 n
/\<\d\{4}\>
精确搜索 4 位数字,与 /\<\d\d\d\d> 相同
**忽略这些\<\>
它们用于精确搜索,例如搜索 fred ->\<fred\>
只会搜索 fred 而不是 alfred。
\( \)
结合整个图案。
PATTERN 这里是您要匹配的模式 -> \s\{1,}
(\s - 空格和 {1,} 如上所述,搜索 1 个或更多空格)
“abc 减法定义”
:%s/\(.\{-}\zs\s\{1,}\)\{2}/,/
输出->“abc 子串,def”
# explanation: first space would be between abc and substring and second
# occurence of the pattern would be between substring and def, hence that
# will be replaced by the "," as specified in replace command above.
这回答了您的实际问题,但不是您的意图。
您询问是否要替换第 n 次出现的单词(但似乎意思是“在一行内”)。这是所问问题的答案,以防有人像我一样发现它=)
对于奇怪的任务(比如需要将每 12 次出现的“狗”替换为“鹦鹉”),我喜欢使用递归记录。
首先将@q中的录音空白
qqq
现在在 q 中开始新的录制
qq
接下来,手动执行您想做的事情(使用上面的示例,将第 12 次出现的“dog”替换为“parrot”):
/dog
nnnnnnnnnnn
删除“狗”并进入插入
diwi
鹦鹉型
parrot
现在播放您当前空的“@q”录音
@q
什么都不做。
最后,停止录制:
q
现在你在@q 中的录音最后会调用自己。但是因为它通过 name调用录音,所以它不会再为空了。所以,调用录音:
@q
它将重播录音,然后在最后,作为最后一步,再次重播自己。它将重复此操作,直到文件结束。
TLDR;
qq
q
/dog
nnnnnnnnnnndiwiparrot<esc>
@q
q
@q
好吧,如果你这样做了,/gc
那么你可以计算它要求你确认的次数,然后在你到达第 n 个时继续替换:D