当表达式中涉及数学除法时,如何使用vim正则表达式替换文本

Eri*_*Sun 5 regex vim eval

我正在使用vim处理如下文本

0x8000   INDEX1 ....
0x8080   INDEX2 ....
....
0x8800   INDEXn ....
Run Code Online (Sandbox Code Playgroud)

我想使用正则表达式来获取每行的索引号.那是

0x8000 ~ 0
0x8080 ~ 1
....
0x8800 ~ n
Run Code Online (Sandbox Code Playgroud)

数学评估应该是(十六进制 - 0x8000)/ 0x80.我试图使用vim正则表达式替换来获得结果

%s/^\(\x\+\)/\=printf("%d", submatch(1) - 0x8000)
Run Code Online (Sandbox Code Playgroud)

这会产生

0     INDEX0
128   INDEX1
....
2048  INDEXn
Run Code Online (Sandbox Code Playgroud)

我想做的是进一步改变它

0     INDEX0
1     INDEX1
...
20    INDEXn
Run Code Online (Sandbox Code Playgroud)

也就是说,我想进一步将第一列除以0x80.这是我遇到问题的时候.

原始参数是"submatch(1) - 0x8000".我现在添加一个"/ 0x80",形成

%s/^\(\x\+\)/\=printf("%d", (submatch(1) - 0x8000)\/0x80)
Run Code Online (Sandbox Code Playgroud)

现在Vim报告错误

Invalid expression: printf("%d", (submatch(1) - 0x8000)\/0x80))
Run Code Online (Sandbox Code Playgroud)

处理"/"时看起来像vim遇到问题.我也试过单个"/"(没有逃脱),但仍然失败.

谁可以帮我这个事?

Mar*_*rth 8

你不能在a中使用分隔字符sub-replace-expression.
来自 :h sub-replace-expression:

Be careful: The separation character must not appear in the expression!
Consider using a character like "@" or ":".  There is no problem if the result
of the expression contains the separation character.

而是将分隔符更改为不再与除法运算符匹配.例如,使用#.

:%s#^\(0x\x\+\)#\=printf("%d", (submatch(1) - 0x8000)/0x80)
Run Code Online (Sandbox Code Playgroud)

请注意,我必须更改您的正则表达式(特别^\(\x\+\)^\(0x\x\+\)).我不知道你为什么为你工作,但是 :h character-classes,\x不应该包括尾随0x:

/\x     \x      \x      hex digit:                      [0-9A-Fa-f] 
Run Code Online (Sandbox Code Playgroud)

此外,你的正则表达式更容易阅读(至少对我来说)使用非常魔法模式(请参阅参考资料:h magic):

:%s#\v^(0x\x+)#\=printf("%d", (submatch(1) - 0x8000)/0x80)
Run Code Online (Sandbox Code Playgroud)