在Vim中交换两个字符串的最简单方法?
用string_b
替换所有出现string_a
的最简单方法是什么,同时将已经为string_b
的任何内容更改为string_a
?我目前的方法如下:在Vim中交换两个字符串的最简单方法?
:s/string_a/string_c/g
:s/string_b/string_a/g
:s/string_c/string_b/g
虽然这个工作,它需要额外的打字,似乎效率低下。有谁知道更好的方法来做到这一点?
我会做这样的:
:%s/\v(foo|bar)/\={'foo':'bar','bar':'foo'}[submatch(0)]/g
但是这太多打字,所以我应该这样做:
function! Mirror(dict)
for [key, value] in items(a:dict)
let a:dict[value] = key
endfor
return a:dict
endfunction
function! S(number)
return submatch(a:number)
endfunction
:%s/\v(foo|bar)/\=Mirror({'foo':'bar'})[S(0)]/g
但是,仍然需要打字foo
和bar
两次,所以我会做这样的事情:
function! SwapWords(dict, ...)
let words = keys(a:dict) + values(a:dict)
let words = map(words, 'escape(v:val, "|")')
if(a:0 == 1)
let delimiter = a:1
else
let delimiter = '/'
endif
let pattern = '\v(' . join(words, '|') . ')'
exe '%s' . delimiter . pattern . delimiter
\ . '\=' . string(Mirror(a:dict)) . '[S(0)]'
\ . delimiter . 'g'
endfunction
:call SwapWords({'foo':'bar'})
如果你的话一个包含/
,你有一个分隔符来传递您知道你的话没有包含,例如
:call SwapWords({'foo/bar':'foo/baz'}, '@')
这也有能够一次交换多对字的好处。
:call SwapWords({'foo':'bar', 'baz':'quux'})
你可以用一个命令做如下图所示我的代码:
:%s/\<\(string_a\|string_b\)\>/\=strpart("string_bstring_a", 8 * ("string_b" == submatch(0)), 8)/g
更新:在计算器的这里编辑让我发疯了,因为它使消除backslahes ...
可以与蒂姆教皇的Abolish插件很容易做到这一点
:%S/{transmit,receive}/{receive,transmit}
%S/{
@JanNetherdrake如果你想使用整个单词,然后使用Subvert的'w'标志。 ':%S/{测试,FOO}/{FOO,测试}/gw'。有关更多信息,请参阅':h abolish-search'。 – 2013-08-07 16:58:23
这是我如何交换两个词skip
& limit
。
%s/skip/xxxxx/g|%s/limit/skip/g|%s/xxxxx/limit/g
很肯定有人可以把它变成这两个参数更短的命令。
您可能(也)想在SuperUser.com上尝试这个问题。 – janmoesen 2010-08-26 19:17:24
这是一个很好的问题 - 人们会认为这很容易......我想一个人可以编写一个接受两个参数的函数,并为您完成三个步骤,但我也希望能够通过快速web搜索来找到这样的函数。 – Jay 2010-08-26 19:33:28
如果您的文件已经在任何地方包含“string_c”,则此方法将失败。如果你是一个人,并且可以选择一个你知道不在你的文件中的单词,这很好,但是教一个函数来猜测一个好的中介词会更困难。最好一次完成。 – 2010-08-26 20:27:26