CJlano
CJlano

Reputation: 1582

vim: substitute characters from backreference

I want to do the following subtitutions in vim: I have a string (with spaces eventually) and a number at the end of the line. I want to create a C #define with that string in uppercase + a prefix + underscores, the number (in hex) and finally the original string as a comment.

For example, from:

hw version 0

to:

#define MY_HW_VERSION (0x00) // hw version

So far, I wrote the following regex:

s/^\(.*\) \(\d\+\)$/#define MY_\U\1\E (0x0\2)\/\/ \1/

which gives

#define MY_HW VERSION (0x00) // hw version

But can you see the space left? MY_HW VERSION instead of MY_HW_VERSION...

So I'd like to make a substitution in the back-reference \1 like \1:s/\s/_/g. Is it possible at all? How to do it?

Thanks!

Upvotes: 3

Views: 1183

Answers (2)

Ingo Karkat
Ingo Karkat

Reputation: 172580

If it's a maximum of two words, you can add additional capture groups:

s/^\(\S\+\) \(\S\+\) \(\d\+\)$/#define MY_\U\1_\2\E (0x0\3)\/\/ \1/

For full flexibility, you can use :help sub-replace-expression; you then need to use string concatenation and Vimscript functions like toupper() instead of \U:

s@^\(.*\) \(\d\+\)$@\='#define MY_' . toupper(tr(submatch(1), ' ', '_')) . '(0x0' . submatch(2) . ') //' . submatch(1)@

Upvotes: 4

Kent
Kent

Reputation: 195059

this would be the one-line :s cmd, works for your example: (I break it into multi-lines, just for better reading)

s@\v(.*) (\d+)@
\='#define MY_'
.toupper(substitute(submatch(1),' ','_','g'))
.' (0x0'.submatch(2).') //'.submatch(1)@

Upvotes: 5

Related Questions