如何在vi中替换匹配的分隔符?

时间:2011-09-15 20:42:52

标签: vim vi replace delimiter

我有一些匹配分隔符的文本(在这种情况下,花括号,文本恰好是LaTeX,这只是偶然的):

\nb{\vec{n},\vec{y}} \in \vec{z}

我想做的是全局用\nb{...}替换(...),同时尊重分隔符的嵌套。即,结果应为

(\vec{n},\vec{y}) \in \vec{z}

而不是

(\vec{n},\vec{y}} \in \vec{z)

这是由:%s/\\nb{\(.*\)}/(\1)/g产生的。标准正则表达式无法处理匹配的分隔符,所以我没想到这种方式可行。我可以使用一些特定于vi的技巧来做到这一点吗?

2 个答案:

答案 0 :(得分:3)

如果您安装了surround.vim,那么以下内容应该可以解决问题

:set nowrapscan
:let @q="/\\m\\\\nb{/e+1\<cr>cs{)dF\\@q"
gg@q

如果你不这样做:

:set nowrapscan
let @q="/\\m\\\\nb{<cr>dt{yi{\"_ca{()\<esc>\"0P@q"
gg@q

概述

创建一个搜索\nb{的递归宏,将光标放在{内,将}{替换为()

细节的荣耀

  • :set nowrapscan这可以防止搜索循环回文件。
  • :let @q="..."将我们的宏存储在q注册表
  • /\m\nb{/e+1搜索\nb{并将光标定位在{
  • 之后
  • cs{)环绕声版本只会更改周围的{ )
  • @q再次运行宏
  • 使用"因此必须逃避一些事情才能正常工作。
  • gg@q转到文件顶部并执行注册q
  • 中的宏

非环绕版本在这里有所不同

  • yi{复制{
  • 内的文字
  • "_ca{()<esc>更改内部文字并包含{,并替换为()
  • "0P将我们刚刚复制的内容粘贴到()

答案 1 :(得分:2)

我会使用以下:global命令。

:g/\\nb{/norm!/^M%r)[{r(dF\\

键入^M Ctrl + V 输入