【问题标题】:Vim - incremental numbering via regular expression search and replaceVim - 通过正则表达式搜索和替换的增量编号
【发布时间】:2014-10-31 18:51:09
【问题描述】:

我有这个代码:

array ('id' => 1, 'name' => "Murka", 'date_of_birth' => "2014-10-31", "breed_id" => 1),
array ('id' => 1, 'name' => "Jurka", 'date_of_birth' => "2014-11-31", "breed_id" => 2),
array ('id' => 1, 'name' => "Nyash", 'date_of_birth' => "2014-12-31", "breed_id" => 3),
array ('id' => 1, 'name' => "Meowy", 'date_of_birth' => "2014-01-31", "breed_id" => 4),
array ('id' => 1, 'name' => "Yummi", 'date_of_birth' => "2014-10-31", "breed_id" => 2),
array ('id' => 1, 'name' => "Barss", 'date_of_birth' => "2014-05-31", "breed_id" => 2),
array ('id' => 1, 'name' => "Nonam", 'date_of_birth' => "2014-05-31", "breed_id" => null

我想更改所有'id' => 1(除了第一个),这样数字就会增加 1。使用 Emacs 很容易实现:

M-x replace-regexp
\(1,\)
\,(1+ \#),

here 所述。经过一些研究,我使用 Vim 所能达到的最大值是(灵感来自 here):

:let i=1 | g/1,/ s//\=i/ | let i+=1

但这会删除以下所有逗号:

array ('id' => 1 'name' => "Murka", 'date_of_birth' => "2014-10-31", "breed_id" => 1),
array ('id' => 2 'name' => "Jurka", 'date_of_birth' => "2014-11-31", "breed_id" => 2),
array ('id' => 3 'name' => "Nyash", 'date_of_birth' => "2014-12-31", "breed_id" => 3),
array ('id' => 4 'name' => "Meowy", 'date_of_birth' => "2014-01-31", "breed_id" => 4),
array ('id' => 5 'name' => "Yummi", 'date_of_birth' => "2014-10-31", "breed_id" => 2),
array ('id' => 6 'name' => "Barss", 'date_of_birth' => "2014-05-31", "breed_id" => 2),
array ('id' => 7 'name' => "Nonam", 'date_of_birth' => "2014-05-31", "breed_id" => null),

所以我必须修复它(我知道这很容易)。

我知道this 和宏,我只是想知道Vim 中是否有任何单行命令解决方案。

更一般的问题:是否可以在 Vim 中注入一些逻辑,如条件语句,操作正则表达式反向引用? Emacs 中的示例如下:

C-M-% \(^.*\)\(linear-gradient(\)\(to right\|to bottom\)\(.*$\) <RET>
\& C-q C-j
\1-prefix-\2\,(if (equal "to right" \3) "left" "top")\4

大约一年多前,这个帮助我重构了一些包含大量内联 CSS 的巨大可怕 HTML 代码。

【问题讨论】:

    标签: regex vim emacs increment substitution


    【解决方案1】:

    对于您的一般性问题,我没有答案,但对于您的具体情况,我有一个答案。您可以通过将逗号置于正向预测中来使您的命令正常工作,如下所示:

    :let i=1 | g/1(\,\)\@=/ s//\=i/ | let i+=1
    

    现在它只会替换1

    【讨论】:

    • 非常感谢,它有效!将此添加到我的收藏夹:)
    • 您可以通过使用\ze 而不是积极的前瞻来简化您的正则表达式。例如:let i=1 | g/1\ze,/ s//\=i/ | let i+=1
    • :让 i=1 | g/1\ze,/s//\=i/ | let i+=1 对我来说真的很实用。请让我知道是否可以选择行的范围。意味着我只需要替换文件中从 10 到 20 的行。我们如何指定:
    【解决方案2】:

    一个非常简单的解决方案:

    :%norm f1s^R=line('.')^M
    

    这样获得:

    :%norm f1s<C-v><C-r>=line('.')<C-v><CR>
    

    如果您不习惯在命令行中输入完整的宏,您可以通过录制获得相同的结果:

    qq
    f1s<C-r>=line('.')<CR>
    q
    [range]@q
    

    【讨论】:

    • 这种方式对我来说有点深奥,但是很管用,我一定会试一试的。非常感谢!
    【解决方案3】:

    另一种方法。转到第二行,将光标放在第一个 1 上,现在开始可视块选择 Ctrl-v,按 j 直到要增加的行并按 g Ctrl-a

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-16
      • 1970-01-01
      • 2010-10-05
      • 2013-06-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多