假设我写了一个简单的CSS规则:
.star_10 {
background: url(stars.png) no-repeat 0 0;
}
我需要10次,所以我复制了9次。
.star_10 {
background: url(stars.png) no-repeat 0 0;
}
.star_10 {
background: url(stars.png) no-repeat 0 0;
}
.star_10 {
background: url(stars.png) no-repeat 0 0;
}
.star_10 {
background: url(stars.png) no-repeat 0 0;
}
.star_10 {
background: url(stars.png) no-repeat 0 0;
}
等
现在我想用增量值更改 star_10 和 0 0 ,所以它看起来像这样:
.star_10 {
background: url(stars.png) no-repeat 0 0;
}
.star_9 {
background: url(stars.png) no-repeat 0 -18px;
}
.star_8 {
background: url(stars.png) no-repeat 0 -36px;
}
.star_7 {
background: url(stars.png) no-repeat 0 -54px;
}
依旧......
那么如何搜索/替换每个实例,进行计算并编写呢?
答案 0 :(得分:57)
您可以使用宏轻松完成。让我们说你只有这个:
.star_10 {
background: url(stars.png) no-repeat 0 0;
}
将光标放在第一个点(.star10
)上,然后在正常模式下键入以下内容:
qa3yy3jp^Xjt;18^Xk0q
解释
qa
将在注册“a”中启动宏录制。3yy
会猛拉(复制)以下3行。3j
会将光标放下3行。p
会粘贴过去的文字。^X
(ctrl + x)将减少星级编号。j
会将光标放下一行。t;
会将光标放在当前行中的下一个;
之前。18^X
会将背景的y坐标减少18; k
会将光标放一行,0
会将光标放在行的开头。q
将完成宏录制。之后,你可能会有这样的事情。
.star_10 {
background: url(stars.png) no-repeat 0 0;
}
.star_9 {
background: url(stars.png) no-repeat 0 -18;
}
就是这样。只需将光标放在.star_9上的点上,然后按8@a
再次执行寄存器a
中记录的宏八次。
答案 1 :(得分:13)
您可以将s/pattern/replace
构造与\=
符号一起使用,以评估函数或表达式,如下所示:
减少.star_10
:
let g:decr = 11
fu! Decr()
let g:decr = g:decr - 1
return g:decr
endfu
:%s/.star_10/\=".star_" . Decr()/
同样,你要做
let g:decr_18 = 18
fu! Decr18()
let g:decr_18 = g:decr_18 - 18
return g:decr_18
endfu
然后用
替换0 0;
:%s/no-repeat 0 0;/\="no-repeat 0 " . Decr18() . "px"/
对于这两个函数,声明一个(全局)变量,该变量在函数内被操作并返回。对于与模式匹配的每一行,都会调用功能区本身。该模式将替换为\=
之后的表达式。
答案 2 :(得分:2)
你可能会为此编写一个函数,但我通常会做一些更简单的事情。我使用一个涉及^ A和^ X键的关键宏(递增和递减一个数字)。使用qa
开始录制,做你的东西,使用带有计数修饰符的那些键(例如18^X
),然后说,10 @ after。
答案 3 :(得分:0)
我需要这个解决方案,但也需要领先的零支持。我对原始问题的使用更像是示例1而不是示例2(这是原始示例)。
我创建了一个名为SearchIncr() (search, replace, and increment)
的函数。
有四个必需参数:target_string
,replacement_string
,start_value
,increment_value
。
还有两个可选参数:leading_zeros
,position
leading_zeros
是正整数值,position
是'之前'或'之后'。见例2.
:'<,'>call SearchIncr("0 0","new",1,5,8)
如果文件如下所示:
what 0 0 post
areu 0 0 post
doin 0 0 post
然后你会得到:
what new00000001 post
areu new00000006 post
doin new00000011 post
:'<,'>call SearchIncr("0;","px;",-18,-18,0,'after')
.star_10 {
background: url(stars.png) no-repeat 0 0;
}
.star_10 {
background: url(stars.png) no-repeat 0 0;
}
.star_10 {
background: url(stars.png) no-repeat 0 0;
}
然后你会得到:
.star_10 {
background: url(stars.png) no-repeat 0 -18px;
}
.star_10 {
background: url(stars.png) no-repeat 0 -36px;
}
.star_10 {
background: url(stars.png) no-repeat 0 -54px;
}
vimscript在这里:
" place functions here
function! SearchIncr(a1,a2,a3,a4,...)
" patn, repl, start, increment
let target = a:a1
let repl = a:a2
let startval = a:a3
let increment = a:a4
" 1st optional argument handles leading zeros
" process optional leading zero
if a:0 >= 1
let leadingz = a:1
else
" default to 0
let leadingz = 0
endif
" 2nd optional argument handles if target string goes before or after
" default is before
if a:0 == 2
" ideally set to 'after'
let repl_pos = a:2
else
let repl_pos = 'before'
endif
" inits
let l:incr = startval - increment
let lnum = a:firstline
" cycle though selection
while lnum <= a:lastline
" the FORMATTING string
if repl_pos == 'before'
let l:incrstring = '\=printf(''%s%0'. leadingz . 'd'',repl,l:incr)'
elseif repl_pos == 'after'
let l:incrstring = '\=printf(''%0'. leadingz . 'd%s'',l:incr,repl)'
else
"default to no leading zero and before placement
let l:incrstring = '\=printf(''%s%0d'',repl,l:incr)'
endif
" only increment counter when target matches
if match(getline(lnum),target) > 0
let l:incr = l:incr + increment
endif
" the search and replace
call setline(lnum,substitute(getline(lnum),target,
\ l:incrstring,'g'))
let lnum = lnum + 1
endwhile
endfunction
任何改进上述内容的评论都将不胜感激!
答案 4 :(得分:0)
仅使用纯vim资源,无需编写脚本:
:let c=10 | g/_\zs\d\+\ze/ s//\=c/ | let c-=1
:let c=0 | g/no-repeat 0 \zs\d\+/ s//\=c/ | let c-=18