Mer*_*ham 15 regex vim counter replace
有没有办法在gVim搜索/替换中插入某种计数器变量的值?
例如转换这个文件:
<SomeElement Id="F" ... />
<SomeElement Id="F" ... />
<SomeElement Id="F" ... />
Run Code Online (Sandbox Code Playgroud)
到这个结果文件:
<SomeElement Id="1" ... />
<SomeElement Id="2" ... />
<SomeElement Id="3" ... />
Run Code Online (Sandbox Code Playgroud)
我想这个命令看起来像:
:%s/^\(\s*<SomeElement Id="\)F\(".*\)$/\1<insert-counter-here>\2/g
Run Code Online (Sandbox Code Playgroud)
我正在使用他们提供的安装程序中最新的Windows版本.我强烈不想安装任何其他工具.
另外,我最好避免安装脚本来支持这一点,但我愿意,如果这是唯一的方法.
ib.*_*ib. 18
使用表达式特征替换可以使用可增加的计数器(请参阅参考资料:help sub-replace-\=).由于\=构造仅允许表达式,:let因此禁止使用该命令,因此无法以通常的方式设置变量.但是,如果该变量是列表或字典,则有一个简单的技巧可以更改表达式中变量的值.在这种情况下,其内容可以由map()函数修改.以这种方式,对问题中描述的情况的替换将如下所示.1
:let n=[0] | %s/Id="F"/\='Id="'.map(n,'v:val+1')[0].'"'/g
Run Code Online (Sandbox Code Playgroud)
或者更好,2
:let n=[0] | %s/Id="\zsF\ze"/\=map(n,'v:val+1')/g
Run Code Online (Sandbox Code Playgroud)
这个简短的单线程完全解决了这个问题.
对于诸如上述的频繁更换,可以定义辅助功能
function! Inc(x)
let a:x[0] += 1
return a:x[0]
endfunction
Run Code Online (Sandbox Code Playgroud)
并使替换命令更短,
:%s/Id="\zsF\ze"/\=Inc(n)/g
Run Code Online (Sandbox Code Playgroud)
1 这里棘手的部分是替换的替代部分.因为它从\=其余部分开始被解释为Vim的表达式.因此,'Id="'.map(n, 'v:val+1').'"'是一个普通的表达.这里'Id="'使用.
函数调用的返回值map(n, 'v:val+1')和另一个字符串连接字符串文字(使用运算符)'"'.函数map需要两个参数:一个列表(如本例所示)或一个字典,以及一个包含表达式的字符串,该表达式应该针对给定列表或字典中的每个项进行评估.特殊变量v:val表示单个列表项.因此,'v:val+1'字符串将被评估为增加1的列表项.
2 的\zs和\ze图案原子用于设置开始和图案的端部,以取代,分别为(见:help /\zs和:help
/\ze).这样,替换命令的整个搜索部分匹配,但只有部分\zs和\ze替换部分.这避免了替代表达式中的笨拙连接.
anu*_*ava 12
嗯,这有点棘手.这是我到目前为止所得到的.在vim会话中尝试这两个map命令:
:nmap %% :let X=1<cr>1G!!
:nmap !! /^\s*<SomeElement Id="F"<cr>:s/F"/\=X.'"'/<cr>:let X=X+1<cr>!!
Run Code Online (Sandbox Code Playgroud)
一旦那是按下%%开始有趣的部分:)
它使您的给定文件为:
<SomeElement Id="1" ... />
<SomeElement Id="2" ... />
<SomeElement Id="3" ... />
<SomeElement Id="4" ... />
Run Code Online (Sandbox Code Playgroud)
第一个 nmap命令将以下序列映射到击键%%:
!!第二个 nmap命令将以下序列映射到击键!!:
^\s*<SomeElement Id="F"F"变量X和引号"!!.用于在vim中串联字符串,非常类似于php当^\s*<SomeElement Id="F"文件中不再找到模式时,此递归调用将停止.
Vim wiki说明似乎是最简单的解决方案(至少对我而言).
下面的实施例的替换所有出现PATTERN与REPLACE_[counter](REPLACE_1,REPLACE_2等等):
:let i=1 | g/PATTERN/s//\='REPLACE_'.i/ | let i=i+1
Run Code Online (Sandbox Code Playgroud)
要回答这个问题,它可能如下所示:
:let i=1 | g/SomeElement Id="F"/s//\='SomeElement Id="'.i.'"'/ | let i=i+1
Run Code Online (Sandbox Code Playgroud)
小智 6
很简单的解决方案 我不得不这样做几次.
:let i=1 | g/^\(\s*<SomeElement Id="\)F\(".*\)$/s//\=submatch(1).i.submatch(2)/ | let i=i+1
Run Code Online (Sandbox Code Playgroud)
基于以下提示.http://gdwarner.blogspot.com/2009/01/vim-search-and-replace-with-increment.html