如何使用VIM将宏和正则表达式的功能结合起来

如何使用VIM将宏和正则表达式的功能结合起来,vim,Vim,我发现自己经常遇到一些问题,需要将正则表达式、某种移动、复制和粘贴结合起来。我确信在vim中有一些方法可以做到这一点,但我还没有看到任何东西将其结合在一起。作为一个例子,我现在试图解决的问题是这样的 查找一行为“/^Description”(.*)”/ 保存捕获的文本 转到“/^TEXT”(.*)所在的行-/ 将上面捕获的文本替换为步骤2中捕获的文本 如有必要,在文件中向前移动时重复此操作 有人知道在VIM中快速自动化此类任务的方法吗?您可以将以下序列映射到未使用的键(如F2),然后按任意次数

我发现自己经常遇到一些问题,需要将正则表达式、某种移动、复制和粘贴结合起来。我确信在vim中有一些方法可以做到这一点,但我还没有看到任何东西将其结合在一起。作为一个例子,我现在试图解决的问题是这样的

  • 查找一行为“/^Description”(.*)”/
  • 保存捕获的文本
  • 转到“/^TEXT”(.*)所在的行-/
  • 将上面捕获的文本替换为步骤2中捕获的文本
  • 如有必要,在文件中向前移动时重复此操作

  • 有人知道在VIM中快速自动化此类任务的方法吗?

    您可以将以下序列映射到未使用的键(如F2),然后按任意次数

    :map <F2> /^Description "(.*)"<CR>y//e/^TEXT "(.*)-<CR>Pd//e
    
    这是您的第二次搜索:

    /^TEXT "(.*)-<CR>
    

    我还没有学会所有新的vim-only特性;我在vim之前就学会了vi,这个解决方案可以在任何vi-ish编辑器中使用。也许有更好的解决方案使用vim特性

    在这种情况下,我通常会使用
    :map
    命令绑定多个键,每个键都执行上述操作的一部分。您需要选择一些可以暂时不用的键;我经常使用
    g
    v
    。@Neil Forrester建议使用功能键,这是一个好主意

    现在,您展示了带有表示匹配组的paren的正则表达式模式。(在vi或vim中,您实际上需要在每个paren前面加一个反斜杠,使其“神奇”;请参阅文档。)但是,对于这个解决方案,我将改为使用
    f
    命令,该命令(f)IND是一个指定的字符;和/或
    t
    命令,它跳转到一个字符。
    f
    跳转到一个字符,其中
    t
    跳转到一个字符前面。因此,使用
    f”
    我们可以跳转到字符串的第一个双引号,然后使用
    t“
    我们可以跳到第二个双引号之前。因此,序列
    f“lyt”
    将找到第一个双引号,向右移动一个字符,然后将所有内容拖动到下一个双引号。但是,让我们将拖动的文本存储到26个命名缓冲区中的一个;让我们只使用缓冲区“a”:
    f“l”ayt“
    这有点让人困惑,因为我们必须使用
    “a
    来指代命名缓冲区“a”,但我们还需要很多其他
    字符

    此外,在“地图”中“您可能需要记录输入键的击键。方法是按Ctrl+V,然后按Enter键。这将显示为
    ^M
    。在下面的“我的代码”中,如果您看到
    ^M
    ,它不是指实际的
    ^
    ,后面跟着实际的
    M
    ,而是表示回车键的单个键

    现在,我们可以制作两个键映射。让我们绑定
    v
    执行步骤1和2,绑定
    g
    执行步骤3和4

    :map v /^Description "/^Mf"l"ayt"
    
    :map g /^TEXT "/^Mf"ldt""aP
    
    不要忘记,使用Ctrl+V和Enter键,而不是实际键入^M,因此您不能在不进行编辑的情况下复制/粘贴上面的内容

    现在,使用
    v
    键执行步骤1和2,使用
    g
    键执行步骤3和4。通过交替地按两个键,你可以做得非常快

    也可以通过在vim中使用脚本来实现这一点,但另一方面,如果要编写脚本,您可能只需要编写一个简短的Python脚本(或您最喜欢的语言)。上面的两个关键宏确实提供了在vim中执行此类操作的快速方法


    vim有一些功能,可以在键入键时录制键,我认为可以使用这些功能快速创建此类宏。

    我通常认为将工作拆分为两个宏是一个好主意。当我做这类事情时,有时一次搜索需要多个替换,有时我想编辑原始行,或者其他任何东西。这一行很好,但我应该更清楚,我想捕获文本中的文本,并使用(.*)匹配。不过,我相信我会发现这里的技术很有用。这就是我一直在寻找的答案。我需要的关键命令是f和t。事实上,我不得不用一个“美国佬”来代替“删除”,但在其他方面是完美的。非常感谢。当然,对于这一点,“yank”比“delete”好;我不知道为什么我认为你在输入“文本”时想从“描述”中删除文本。我会继续编辑答案,这样以后的读者就不会感到困惑了。
    y//e
    
    /^TEXT "(.*)-<CR>
    
    Pld//e
    
    :map v /^Description "/^Mf"l"ayt"
    
    :map g /^TEXT "/^Mf"ldt""aP