How can I use vim regex to replace text when math division is involved in expression

I am using vim to process text like this

0x8000   INDEX1 ....
0x8080   INDEX2 ....
....
0x8800   INDEXn ....

      

I want to use a regex to get the index number of each line. i.e

0x8000 ~ 0
0x8080 ~ 1
....
0x8800 ~ n

      

The mathematical score should be (hex - 0x8000) / 0x80. I am trying to use vim regex replacement to get the result in a string

%s/^\(\x\+\)/\=printf("%d", submatch(1) - 0x8000)

      

This will give

0     INDEX0
128   INDEX1
....
2048  INDEXn

      

What I want to do is change it to

0     INDEX0
1     INDEX1
...
20    INDEXn

      

That is, I want to still split the first column 0x80. This is when I get the problem.

The original argument is "send (1) - 0x8000". Now I add "/ 0x80" to it, which forms

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

      

Now the Vim error message

Invalid expression: printf("%d", (submatch(1) - 0x8000)\/0x80))

      

It looks like vim is having a problem handling the "/". I also tried with one "/" (no exit) but still doesn't work.

Can anyone help me with this?

+4


source to share


1 answer


You cannot use a separator character in sub-replace-expression

.
From :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.

Instead, change the delimiter so that it no longer matches the division operator. For example use #

.

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

      



Please note that I had to change your regex (specifically ^\(\x\+\)

to ^\(0x\x\+\)

). I don't know why yours works for you, but from :h character-classes

, \x

shouldn't include the final 0x

:

/\x     \x      \x      hex digit:                      [0-9A-Fa-f] 

      


Also, your regex is a little easier to read (at least for me) using very magic mode (see :h magic

):

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

      

+7


source







All Articles