Skip to main content
 首页 » 编程设计

regex之Vim中的数学搜索和替换

2024年11月24日31www_RR

我有一个带有时间(分钟和秒)的文件,该文件看起来大致如下:

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)是神奇的部分。我知道我可以使用特殊寄存器 =插入评估结果,但是有没有办法在正则表达式的子部分中执行此操作?

请您参考如下方法:

像这样吗

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