有没有办法在gVim search / replace中插入某种计数器变量的值?
e.g。转换此文件:
<SomeElement Id="F" ... />
<SomeElement Id="F" ... />
<SomeElement Id="F" ... />
到这个结果文件:
<SomeElement Id="1" ... />
<SomeElement Id="2" ... />
<SomeElement Id="3" ... />
我想这个命令看起来像是:
:%s/^\(\s*<SomeElement Id="\)F\(".*\)$/\1<insert-counter-here>\2/g
我使用的是最新的Windows版本,来自他们提供的安装程序。我强烈不想安装任何其他工具。
另外,我最好避免安装脚本来支持这一点,但我愿意,如果这是唯一的方法。
答案 0 :(得分:18)
可以使用替换来增加一个计数器
表达特征(见:help sub-replace-\=
)。自\=
构造以来
只允许表达式,禁止使用:let
命令,和
因此,变量无法按常规方式设置。但是,有
一个简单的技巧来改变表达式中变量的值
变量是列表或字典。在这种情况下,其内容可能是
由map()
函数修改。以这种方式,替代案件
问题中描述的内容如下: 1
:let n=[0] | %s/Id="F"/\='Id="'.map(n,'v:val+1')[0].'"'/g
或者更好, 2
:let n=[0] | %s/Id="\zsF\ze"/\=map(n,'v:val+1')/g
这个简短的单行完全解决了这个问题。
对于如上所述的频繁更换,可以定义辅助设备 功能
function! Inc(x)
let a:x[0] += 1
return a:x[0]
endfunction
并使替换命令更短,
:%s/Id="\zsF\ze"/\=Inc(n)/g
1 这里棘手的部分是在替代部分
替换。由于它以\=
开头,因此其余部分被解释为
由Vim表达。因此,'Id="'.map(n, 'v:val+1').'"'
是普通的
表达。这里连接了一个字符串文字'Id="'
(使用.
operator)具有函数调用map(n, 'v:val+1')
的返回值,并带有
另一个字符串'"'
。函数map
需要两个参数:一个列表(如
这种情况)或字典,以及包含表达式的字符串
评估给定列表或字典中的每个项目。特别
变量v:val
表示单个列表项。所以'v:val+1'
字符串
将被评估为增加一个的列表项。
2 \zs
和\ze
模式原子用于设置开始和
分别替换模式的结尾(参见:help /\zs
和:help
/\ze
)。这样,匹配命令的整个搜索部分匹配,
但只有\zs
和\ze
之间的部分被替换。这避免了笨拙
替代表达式中的连接。
答案 1 :(得分:12)
嗯,这有点棘手。这是我到目前为止所得到的。在vim会话中尝试这两个map命令:
:nmap %% :let X=1<cr>1G!!
:nmap !! /^\s*<SomeElement Id="F"<cr>:s/F"/\=X.'"'/<cr>:let X=X+1<cr>!!
一旦有,请按%%
启动有趣的部分:)
它使您的给定文件为:
<SomeElement Id="1" ... />
<SomeElement Id="2" ... />
<SomeElement Id="3" ... />
<SomeElement Id="4" ... />
第一个 nmap命令将以下序列映射到击键%%
:
!!
第二个 nmap命令将以下序列映射到击键!!
:
^\s*<SomeElement Id="F"
F"
和引用X
"
!!
.
用于连接vim中的字符串,非常类似于php 当文件中找不到模式^\s*<SomeElement Id="F"
时,此递归调用将停止。
答案 2 :(得分:7)
Vim wiki instructions似乎是最简单的解决方案(至少对我而言)。
以下示例将PATTERN
的所有出现替换为REPLACE_[counter]
(REPLACE_1
,REPLACE_2
等):
:let i=1 | g/PATTERN/s//\='REPLACE_'.i/ | let i=i+1
要回答这个问题,可能会是这样的:
:let i=1 | g/SomeElement Id="F"/s//\='SomeElement Id="'.i.'"'/ | let i=i+1
答案 3 :(得分:6)
非常简单的解决方案。我必须多次这样做。
:let i=1 | g/^\(\s*<SomeElement Id="\)F\(".*\)$/s//\=submatch(1).i.submatch(2)/ | let i=i+1
基于以下提示。 http://gdwarner.blogspot.com/2009/01/vim-search-and-replace-with-increment.html
答案 4 :(得分:1)
将其放入vimrc或在当前会话中执行:
function! Inc(x)
let a:x[0] += 1
return a:x[0]
endfunction
function IncReplace(pos, behind, ahead, rep)
let poss=a:pos-1
let n=[poss]
execute '%s/' . a:behind . '\zs' . a:rep . '\ze' . a:ahead . '/\=Inc(n)/g'
endfunction
然后执行:call IncReplace(1, 'Id="', '"', 'F')
第一个参数是您想要开始的数字,第二个参数是您要在数字后面匹配的数字,第三个参数是您希望在数字之前匹配的数字,第四个是您实际想要替换的数字。
答案 5 :(得分:0)
也许plugin increment.vim会有所帮助