我正在使用 vim环绕.vim插件并希望sin(...)
用sin[...]
(很长)数学表达式(包含匹配的括号)中的所有出现替换。
输入示例:
sin(A*(B+C))+sin((X+Y)*sin((A+D)*C))
想要的输出:
sin[A*(B+C)]+sin[(X+Y)*sin[(A+D)*C]]
目前,我首先搜索/sin\zs(
跳转到下一个
sin
表达式,光标位于(
,然后键入cs(]
以替换匹配的括号。然后,我可以使用n
(搜索下一个)和.
(重复上一个命令)重复这两个命令。这可行,但很麻烦,因为表达式太大。
有没有一种方法可以使整个命令序列自动化,或者如何vim
以完全自动化的方式进行内部替换?
可能还有完全其他的方法可以在 vim 之外进行转换,但出于教育原因,我对vim解决方案到问题。
答案1
这是一个典型的案例,递归宏可以帮助。只需将您的按键序列放入递归宏中并运行它即可。为了不激怒SE大神,总结一下wiki文章:
- qqq- 清除
q
寄存器 - qq- 开始录制宏
q
/\msin\zs(
Enter- 找到sin(
,并将光标保留在(
- cs(]- 替换
(...)
为[...]
(使用]而不是[避免添加额外的空格) - @q- 运行
q
宏(由于寄存器为空,所以暂时不执行任何操作q
) - q- 结束录制宏。
然后运行您刚刚录制的宏:@q。就这样,@q
最后的 the 使宏调用本身。它在第一个错误时停止,即/sin(
不再找到任何内容时。
附带说明:如果您不想将该更改应用于整个文件,而只想在第 10 行和第 20 行之间应用该更改,但仍使用递归来避免手动确认,则可以使用\%>...l
和\%<...l
使您的正则表达式仅匹配在您想要的限制之间:/\m\%>9l\%<21lsin\zs(
.