Математика в поиске и замене Vim

У меня есть файл со временем (минуты и секунды), который выглядит примерно следующим образом:

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) - магическая часть. Я знаю, что могу вставить результаты оценки в специальный регистр =, но есть ли способ сделать это в подстроке регулярного выражения?

Ответ 1

Что-то вроде этого?

:%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 ().

Ответ 2

Используйте 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...