如何在vim中重新编号列表?

7

我写了一个网页部分,其中包括以下内容...

<span id="item01">   some first presented text</span>
<span id="item02">   some other text, presented second</span>
<span id="item03">   more text</span>
....
<span id="item15">  last bit of text.</span>

我后来意识到它应该从14到0编号,而不是1到15。(是的,这是我设计不好,没有先规划JavaScript。)

问题是,vim中是否有一种简单的方法可以对正则表达式中的数字进行数学运算?我想在文本“item [00-99]”上进行搜索,并返回文本“item(15-原始数字)”。

搜索似乎很容易 - / item([0-9] [0-9])/(括号将找到的数字放入缓冲区),但是对此进行数学运算甚至可能吗?
在vim中制作带编号列表的宏?提供了一种从头开始编号的方法,但我正在寻找重新编号的方法。


似乎这种东西应该从数组中以编程方式生成,而不是在HTML中硬编码?只是一个想法。 - Mark Reed
就像我说的那样,这是我的设计问题 :) 我正在生成一个固定大小的文本网格(每个单元格中的文本可变)。我最初将(0,0)坐标放在左上角,但是网格的数学坐标系将(0,0)放在左下角。我希望能够根据需要仅访问每个单元格,而不是在每次更新时输出整个表格。 - Jest Phulin
4个回答

12
:%s/item\zs\d\+/\=15 - submatch(0)/

将会按照您的意愿进行操作。
分解如下:

  • item\zs\d\+: 匹配 item 后面的数字(\zs 表示匹配的开始位置)
  • \=: 表示替换是一个表达式
  • 15 - submatch(0): 返回匹配到的数字减去 15 的结果

1
由于使用了\zs,您可以在正则表达式中省略括号,并且在替换中只引用submatch(0)而不是submatch(1) - Mark Reed
1
我建议使用g命令,只将替换应用于包含“item”的行::%g/item/s/\d\+/\=15 - submatch(0)/。这样可以摆脱\zs(即使有些人可能会认为它比原始答案不够精确)。 - Jérôme Pouiller

6

另一种有趣的方法是使用 g<CTRL-a>:help v_g_CTRL-A 查看更多信息)

从这里开始:

<span id="item01">   some first presented text</span>
<span id="item02">   some other text, presented second</span>
<span id="item03">   more text</span>
....
<span id="item15">  last bit of text.</span>

使用可视化块模式将所有数字重置为00

  • <CTRL-V> 选择所有数字
  • r0 用零替换所有数字

你应该看到:

<span id="item00">   some first presented text</span>
<span id="item00">   some other text, presented second</span>
<span id="item00">   more text</span>
....
<span id="item00">  last bit of text.</span>

现在使用gv恢复您的块选择,或者使用V选择所有行并按下g<CTRL+a>

<span id="item01">   some first presented text</span>
<span id="item02">   some other text, presented second</span>
<span id="item03">   more text</span>
....
<span id="item015">  last bit of text.</span>

很遗憾这里还需要进行最后一次清理。正如你所看到的,所有两位数前面都有一个0。使用可视块模式<CTRL+v>再次选择并删除不需要的零。

<span id="item01">   some first presented text</span>
<span id="item02">   some other text, presented second</span>
<span id="item03">   more text</span>
....
<span id="item15">  last bit of text.</span>

现在你已经完成了 :)

2

如果你的vim已经安装了perl插件(许多发行版默认安装),你可以使用:perldo命令来实现。 (@Marth 的方法更好)

:perldo s/(?<=item)(\d+)/15 - $1/e

2
你可能想看一下VisIncr 插件。它可以增加/减少数字、日期和星期几等各种格式的列支持。处理这些内容时非常方便。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接