Regex 替换vim中出现的第n个单词
我看到了关于查找单词/模式的第n次出现的其他问题,但我找不到如何在vim中替换模式的第n次出现。有一种明显的方法可以对所有事件进行硬编码,如Regex 替换vim中出现的第n个单词,regex,vim,sed,substitution,Regex,Vim,Sed,Substitution,我看到了关于查找单词/模式的第n次出现的其他问题,但我找不到如何在vim中替换模式的第n次出现。有一种明显的方法可以对所有事件进行硬编码,如 :s/.*\(word\).*\(word\).*\(word\).*/.*\1.*\2.*newWord.*/g 有更好的方法吗 好吧,如果你做了/gc,那么你可以计算它要求你确认的次数,并在你到达第n:D时继续进行替换你可以通过使用多个搜索来做这件事。:s/pattern/repl/命令中的空模式表示替换最近的搜索结果 :/word//word//
:s/.*\(word\).*\(word\).*\(word\).*/.*\1.*\2.*newWord.*/g
有更好的方法吗 好吧,如果你做了
/gc
,那么你可以计算它要求你确认的次数,并在你到达第n:D时继续进行替换你可以通过使用多个搜索来做这件事。:s/pattern/repl/
命令中的空模式表示替换最近的搜索结果
:/word//word//word/ s//newWord/
or
:/word//word/ s/word/newWord/
然后,您可以通过执行@:
,或者甚至执行10@:
将该命令重复10次,来重复多次
或者,如果我以交互方式执行此操作,我会执行以下操作:
3/word
:s//newWord/r
这将找到从光标开始的第三个单词,然后执行替换。有关信息
s/\%(\(pattern\).\{-}\)\{41}\zs\1/2/
也可以替换第42次出现。然而,我更喜欢哪一个更简单——即使它不会局限于当前行。这回答了您的实际问题,但不是您的意图 您询问是否替换一个单词的第n次出现(但似乎表示“在一行内”)。以下是问题的答案,以防有人像我一样发现它=) 对于奇怪的任务(比如需要用“parrot”替换第12次出现的“dog”),我喜欢使用递归录音 首先在@q中清空录音
qqq
现在在q中开始一个新的录音
qq
接下来,手动执行您想要执行的操作(使用上面的示例,将第12次出现的“dog”替换为“parrot”):
删除“dog”并进入insert
diwi
类型鹦鹉
parrot
现在播放您当前的空“@q”录音
@q
这没什么用
最后,停止录制:
q
@q
现在,您在@q中的录制在结尾处自动调用。但是因为它按名称调用录音,所以它不再是空的。因此,请调用录音:
q
@q
它将重放录音,然后在最后,作为最后一步,再次重放自己。它将重复此操作,直到文件结束
TLDR
qq
Q
/狗
nnnnnnnn迪维帕罗
@q
Q
@q
用Replace替换一行中每第n次出现的图案
:%s/\(\zsPATTERN.\{-}\)\{N}/REPLACE/
为了替换vim中一行中第n次出现的模式,除了上面的答案,我只想解释模式匹配,即它实际上是如何工作的,以便于理解 因此,我将讨论
\(.{-}\zsPATTERN\){N}
解决方案
我将使用的示例是替换句子(字符串)中第二次出现的超过1个空格。
根据模式匹配代码->
\zs
-水平滚动文本,将光标定位在起始位置(左侧)
屏幕的侧面)\{-}
0或更多尽可能少(*)
在这里。匹配任意字符和{}次。
e、 这里的gab{2,3}c与b出现的地方匹配2次或3次
在这种情况下,我们还可以使用*
,它是0或尽可能多。
根据vim非贪婪文档,“{-}”与“*”相同,但使用最短匹配优先算法\{N}
->匹配前面原子的N
/\
搜索精确的4位数字,与/\
**忽略这些\
它们是用于精确搜索的,就像搜索fred->\
将只搜索fred而不是alfred\(\)
组合整个模式\s\{1,}
(\s-space和{1,}如上所述,搜索1个或多个空间)是的,但是我想在没有确认的情况下替换第n次出现的单词(就像我必须写一个脚本来做一样)。Hrm,这仍然有很多问题,如果第一个单词是我们正在寻找的单词,“3/单词”将使我们进入第四次出现。此外,当我在找到第n个实例后尝试替换时,它仍然替换第一个匹配项。
3/word
将查找从光标开始的第三个匹配项。如果要从文件的顶部开始,请使用gg
。请注意,3/word
相当于键入/word
三次,因此它肯定会找到第三个匹配项。-1:如果所有单词都在同一行上,这两个选项对我都不起作用(这是我假设OP的意思)。在这两个例子中,替换仍然发生在行中的第一个单词上。显然在sed中有替换,但在vims///
中没有替换:@Luc Hermitte:你能告诉我你的答案中“\%”是什么意思吗。它似乎是VIM无法识别的运算符。它类似于\(
),但它告诉我们不要将括号中匹配的内容绑定到\1
。请参见:h/\%(
,iirc,你能告诉我zs
和{N}
是正则表达式的语法还是VIM的语法吗?缩放锚是VIM特定的吗(其他语言IDK),请参见Vim中的about\zs
或type:h\zs
以获取有关它的信息,大多数语言中都使用了{}
,但功能不同,主要用于匹配长度或模式或组匹配的出现时间(..){N}
,就像我在这里使用的那样。
:%s/\(.\{-}\zs\s\{1,}\)\{2}/,/
# 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.