在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 

虽然这个工作,它需要额外的打字,似乎效率低下。有谁知道更好的方法来做到这一点?

+2

您可能(也)想在SuperUser.com上尝试这个问题。 – janmoesen 2010-08-26 19:17:24

+0

这是一个很好的问题 - 人们会认为这很容易......我想一个人可以编写一个接受两个参数的函数,并为您完成三个步骤,但我也希望能够通过快速web搜索来找到这样的函数。 – Jay 2010-08-26 19:33:28

+1

如果您的文件已经在任何地方包含“string_c”,则此方法将失败。如果你是一个人,并且可以选择一个你知道不在你的文件中的单词,这很好,但是教一个函数来猜测一个好的中介词会更困难。最好一次完成。 – 2010-08-26 20:27:26

我会做这样的:

:%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 

但是,仍然需要打字foobar两次,所以我会做这样的事情:

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'}) 
+0

这太棒了!我唯一的问题是,它在任何地方交换事件。有没有办法让你想要交换的行出现类似于'17,3,4s/foo/bar/g'只会替代17到34行的行? – dsg 2010-12-27 19:44:45

+1

@dsg可以通过对SwapWords()进行两处更改来完成。在第一行的'...)'之后放置关键字'range',然后用'a:firstline替换'%s''。 ','。 a:最后一行。 “s''。然后它会像':s'一样完全采用一个范围。 – 00dani 2013-08-02 11:39:14

你可以用一个命令做如下图所示我的代码:

:%s/\<\(string_a\|string_b\)\>/\=strpart("string_bstring_a", 8 * ("string_b" == submatch(0)), 8)/g 

更新:在计算器的这里编辑让我发疯了,因为它使消除backslahes ...

可以与蒂姆教皇的Abolish插件很容易做到这一点

:%S/{transmit,receive}/{receive,transmit} 
+0

%S/{,}/{,}/g 当我尝试对换整个单词时,它不起作用。我该怎么办? – 2013-08-07 16:45:57

+1

@JanNetherdrake如果你想使用整个单词,然后使用Subvert的'w'标志。 ':%S/{测试,FOO}/{FOO,测试}/gw'。有关更多信息,请参阅':h abolish-search'。 – 2013-08-07 16:58:23

swapstrings plugin为此提供了一个方便的命令:

:SwapStrings string_a string_b 

这是我如何交换两个词skip & limit

%s/skip/xxxxx/g|%s/limit/skip/g|%s/xxxxx/limit/g

很肯定有人可以把它变成这两个参数更短的命令。