使用Vim的Ex模式从一组线条复制模式

时间:2013-12-11 10:01:35

标签: regex vim vi ex

我正在整理我的vimrc。

任务:
- 在单引号内复制内容(最好在斜线后)
- 将它们粘贴在第1行

之下
1: Name:
2: 
3: Bundle 'tpope/vim-rails'
4: Bundle 'tpope/vim-endwise'
5: Bundle 'mileszs/ack.vim'
6: Bundle 'scrooloose/nerdcommenter'
7: Bundle 'kana/vim-textobj-entire'
8: Bundle 'kana/vim-textobj-user'

我知道

:{source_address}t{target_address}

Ex命令,我知道它接受模式。但是,我仍然无法做到恰到好处。我对正则表达式也很新,所以请耐心等待。我尝试了一些东西(在视觉选择上

:'<,'>/\/.*\'t1

我尝试匹配以下模式:

  • 以/
  • 开头
  • 可能包含中间的东西。*
  • 以'
  • 结尾

显然我在某种程度上已经离开了。有任何想法吗?

4 个答案:

答案 0 :(得分:2)

:t复制整行,而不是matchstr

要实现您的目标,您需要matchstr()功能。

此行将执行类似的操作,但顺序相反。希望你没问题:

:'<,'>g/\/.*'/call append(1,matchstr(getline('.'),@/))

例如,如果我只选择前两个“Bundle”行,并执行cmd,我得到:

1: Name:
/vim-endwise'
/vim-rails'
2: 
3: Bundle 'tpope/vim-rails'
4: Bundle 'tpope/vim-endwise'
.... (other lines)
你看到订单是相反的。

要保留订单,您可以选择:

  • 用列表编写脚本
  • 选择那些“反转”行,并执行'<,'>g/.*/m1
  • 将matchstr分配给reg x和2put! x

答案 1 :(得分:2)

  1. 挡住街区。
  2. 把它放在你想要的地方。
  3. 删除您不想要的内容。
  4. 假设光标在第1行的某处:

    :3,8t.
    :'[,norm dt/$x
    

    说明:

    • '[']标记了最新更改的开始和结束。
    • 我们希望范围从第一个Bundle行开始,因此我们以'[标记开始。我们可以简单地使用2,但这不那么“神奇”。
    • 它以我们可以省略的当前行结束,因为它是默认值。
    • 我们使用:normal从命令行执行正常模式命令。
    • 我们会删除第一个/dt/)并删除行中的最后一个字符$x)

    另一种方式:

    :3,8t.
    v'[
    :'<,'>s/.*\/\(.*\)'/\1 ('<,'> being inserted automatically)
    

答案 2 :(得分:0)

你正在做的事情的问题是ex命令在线上工作,而不是像你想的那样在线的部分工作。您无法直接使用:t命令来复制所需内容。

可能有一种方法可以完全按照您的想法进行操作,但是我要做的就是完成您想要的操作:复制所有的第3-8行,将它们粘贴到第1行下方,然后然后隔离你感兴趣的文本。

有很多方法可以复制一系列线条。如果您需要帮助,请发表评论并询问。

现在我们如何在斜线后隔离引号中的部分?我们可以使用你写的基本相同的模式进行替换:

:'<,'>s/.*\/\(.*\)'/\1

答案 3 :(得分:0)

:t / :copy命令(与大多数Ex命令一样)始终复制整行,而不是其中的一部分。为此,您需要:substitute,并在其替换表达式中使用副作用将它们收集到寄存器中。 Copy the search results into clipboard Vim Tips Wiki页面解释了这一点。

使用我的ExtractMatches plugin,这很容易做到:

:3,$YankMatchesToReg#/\zs.*\ze'#
:1put

这使用/.*'模式,并限制匹配(使用\zs\ze原子)以排除前导斜杠和尾随引号。

如果没有插件,可能更容易复制整行,然后使用:s修剪不需要的内容,如@ pandubear的回答所示。