在 Vim 中交换两个字符串的最简单方法是什么?

发布于 2024-09-16 07:34:37 字数 300 浏览 6 评论 0原文

将所有出现的 string_a 替换为 string_b 同时将任何已经是 string_b 的内容更改为 string_a 的最简单方法是什么?我当前的方法如下:

:s/string_a/string_c/g  
:s/string_b/string_a/g  
:s/string_c/string_b/g  

虽然这有效,但它需要额外的输入并且似乎效率低下。有谁知道更好的方法来做到这一点?

What is the easiest way to replace all occurrences of string_a with string_b while at the same time changing anything that was already string_b into string_a? My current method is as follows:

:s/string_a/string_c/g  
:s/string_b/string_a/g  
:s/string_c/string_b/g  

Although this works, it requires extra typing and seems inefficient. Does anybody know of a better way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

节枝 2024-09-23 07:34:37

我会这样做:

:%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'})

如果你的一个单词包含 /,你必须传入一个你知道你的单词都不包含的分隔符,.eg

:call SwapWords({'foo/bar':'foo/baz'}, '@')

这还有一个好处就是能够交换多个对一次的言语。

:call SwapWords({'foo':'bar', 'baz':'quux'})

I'd do it like this:

:%s/\v(foo|bar)/\={'foo':'bar','bar':'foo'}[submatch(0)]/g

But that's too much typing, so I'd do this:

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

But that still requires typing foo and bar twice, so I'd do something like this:

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

If one of your words contains a /, you have to pass in a delimiter which you know none of your words contains, .e.g

:call SwapWords({'foo/bar':'foo/baz'}, '@')

This also has the benefit of being able to swap multiple pairs of words at once.

:call SwapWords({'foo':'bar', 'baz':'quux'})
花之痕靓丽 2024-09-23 07:34:37

您可以使用 Tim Pope 的 Abolish 插件轻松完成此操作

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

You can do this easily with Tim Pope's Abolish plugin

:%S/{transmit,receive}/{receive,transmit}
请你别敷衍 2024-09-23 07:34:37

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

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

很确定有人可以将其变成一个更短的命令,它接受两个参数。

Here is how I swap two words skip & limit:

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

Pretty sure someone could turn it into a shorter command which accepts two arguments.

枯寂 2024-09-23 07:34:37

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

:SwapStrings string_a string_b

The swapstrings plugin provides a handy command for this:

:SwapStrings string_a string_b
つ可否回来 2024-09-23 07:34:37

您可以使用单个命令来完成此操作,如下面的代码所示:

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

You can do it with a single command as shown in my code below:

:%s/\<\(string_a\|string_b\)\>/\=strpart("string_bstring_a", 8 * ("string_b" == submatch(0)), 8)/g
泪之魂 2024-09-23 07:34:37

下面是如何交换一行内由空格键分隔的 2 个字符串的示例。可以使用:

:'a,'bs/\(.*\s\)\(.*$\)/ \2 \1/g

where 'a,'b defines section where this command is applied
      .*\s specifies string from begin of the line until space bar (\s)
      .*$  specifies the section until the end of the line
      \2 \1  in substitution use first section 2 and then section 1

Here is an example how to swap 2 strings separated by space bar within one line. One can use:

:'a,'bs/\(.*\s\)\(.*$\)/ \2 \1/g

where 'a,'b defines section where this command is applied
      .*\s specifies string from begin of the line until space bar (\s)
      .*$  specifies the section until the end of the line
      \2 \1  in substitution use first section 2 and then section 1
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文