递减时,Vim错误地删除了零

时间:2017-05-20 13:10:30

标签: vim

Vim在递减时从某些数字前面删除零:

如果我带有以下文本文件:

a02 
a03
a04
a05
a06
a07
a08
a09  
a10
a11

使用ctrl+V突出显示第二列和第三列,然后点击ctrl+X递减,我留下:

a01
a02
a03
a04
a05
a06
a7
a8
a9
a10

我正在运行Vim版本7.4.1689并且我在没有我的.vimrc的情况下通过

加载它
$ vim -u NONE

2 个答案:

答案 0 :(得分:6)

这是因为Vim会自动识别并转换八进制值。

来自帮助(:h variables):

  

从数字转换为字符串是通过使用ASCII表示   号码。

     

示例:

   Number 123      -->     String "123"
   Number 0        -->     String "0"
   Number -1       -->     String "-1"
     

将字符串转换为数字是通过将第一个数字转换为   一个号码。十六进制" 0xf9",八进制" 017"和二进制" 0b10"编号是   认可。如果字符串不以数字开头,则结果为零。

     

示例:

   String "456"    -->     Number 456
   String "6bar"   -->     Number 6
   String "foo"    -->     Number 0
   String "0xf1"   -->     Number 241
   String "0100"   -->     Number 64
   String "0b101"  -->     Number 5
   String "-8"     -->     Number -8
   String "+8"     -->     Number 0

您的值0207被识别为有效八进制值并保留为原样,通过01递减到八进制06

当您到达08时,它不是有效的八进制值。它被视为字符串08,转换为十进制值8,并递减为709再次发生这种情况,最终为8

1011值也会递减为十进制。由于10是十进制的,而不是八进制,因此您在结果0值中无法获得前导9

我不知道如何通过递减命令来做你想做的事。

编辑:在找到this answer之后,我测试了这个表达式,它会在这个特定情况下执行您要执行的操作:

:%s/\v[0-9]+/\=printf("%02d", substitute(submatch(0), '^0\+', '', 0)-1)/

我不确定这是否解决了您的一般用例,因为它与使用选择的原始操作完全不同。但对于您提供的文件,它可以实现您所追求的结果。

解释一下解释一下:

首先,我们首先调用全局子命令%s并传递\v标志以启用"非常神奇的"模式。这可能会也可能不会根据您的设置更改行为,但这是一个公开示例,因此它包含在此处以确保模式处于活动状态。

:%s/\v

然后,我们找到所有连续的数字序列。这将从您的示例中找到0203等。

[0-9]+

然后在替换部分,我们有了这个命令,它完成了真正的工作:

\=printf("%02d", substitute(submatch(0), '^0\+', '', 0)-1)

substitute()函数确定新值是什么。 submatch(0)表示使用整场比赛。使用^0\+的模式和替换(空字符串)表示从任何具有一个的数字中去除前导零。最后的0并不重要;它只是说substitute()函数没有标志。

substitute命令的结果是一个数字。说02已被删除为2。使用最后的- 1,我们从该结果中减去1(减量)。

最后,此结果将传递给printf函数。使用格式字符串%02d表示以2位宽格式打印十进制值,使用前导零填充。

答案 1 :(得分:3)

如果您希望Vim将所有数字视为小数,您可能需要将以下行添加到.vimrc中:

set nrformats=