Vim中的数学搜索和替换

时间:2013-09-18 16:20:43

标签: regex vim evaluation

我有一个包含时间(分钟和秒)的文件,大致如下所示:

02:53 rest of line 1...
03:10 rest of line 2...
05:34 rest of line 3...
05:35 rest of line 4...
10:02 rest of line 5...
...

我想在几秒钟内用等效时间替换时间。理想情况下,我想运行这样一个神奇的命令:

:%s/^\(\d\d\):\(\d\d\) \(.*\)/(=\1*60 + \2) \3/g

...... (=\1*60 + \2)是神奇的部分。我知道我可以使用特殊寄存器=插入评估结果,但有没有办法在正则表达式的替代部分执行此操作?

3 个答案:

答案 0 :(得分:32)

这样的东西?

:%s/^\(\d\d\):\(\d\d\)/\=submatch(1)*60+submatch(2)/

当替换以\=开始时,替换被解释为表达式。

:h sub-replace-expression复制在

下面
Substitute with an expression           *sub-replace-expression*
                        *sub-replace-\=*
When the substitute string starts with "\=" the remainder is interpreted as an
expression.  This does not work recursively: a substitute() function inside
the expression cannot use "\=" for the substitute string.

The special meaning for characters as mentioned at |sub-replace-special| does
not apply except for "<CR>", "\<CR>" and "\\".  Thus in the result of the
expression you need to use two backslashes to get one, put a backslash before a
<CR> you want to insert, and use a <CR> without a backslash where you want to
break the line.

For convenience a <NL> character is also used as a line break.  Prepend a
backslash to get a real <NL> character (which will be a NUL in the file).

When the result is a |List| then the items are joined with separating line
breaks.  Thus each item becomes a line, except that they can contain line
breaks themselves.

The whole matched text can be accessed with "submatch(0)".  The text matched
with the first pair of () with "submatch(1)".  Likewise for further
sub-matches in ().

答案 1 :(得分:5)

使用submatch()引用替换位置中的分组部分:

:%s/\v^(\d{2}):(\d{2})>/\=submatch(1) * 60 + submatch(2)/

用你的例子得出:

173 rest of line 1...
190 rest of line 2...
334 rest of line 3...
335 rest of line 4...
602 rest of line 5...

答案 2 :(得分:0)

希望这对其他人有帮助,但是我遇到了类似的问题,我想用其他数字替换“ id”,实际上是其他任何数字

{"id":1,"first_name":"Ruperto","last_name":"Bonifayipio","gender":"Male","ssn":"318-69-4987"},

使用的表达式

%s/\v(\d+),/\=submatch(1)*1111/g

产生以下新值

{"id":1111,"first_name":"Ruperto","last_name":"Bonifayipio","gender":"Male","ssn":"318-69-4987"},