Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vim substitution with mathematical expression

I need to replace following line:

[rescap] l=1.2u w=1.5u 

by

[rescap] l=1.2u w=1.5u r=0.8k

value of r 0.8k is l/w

I am trying in vim (already done in perl but wanted to implement using vim)

:s/l=\\(.\*\\)u w=\\(.\*\\)u/l=\1u w=\2u r=\1*\2k/

but it does not evaluate expression and prints:

[rescap] l=1.2u w=1.5u r=1.2*1.5k

If I try \= which evaluates expression it assumes l and w as variable and throws out error.

:s/l=\\(.\*\\)u w=\\(.\*\\)u/\=l=\1u w=\2u r=\1*\2/    

I have to run above expression using vim -s scriptfile through many files. just need to figure out the above substitution statement.

like image 479
user2508758 Avatar asked Jun 14 '16 07:06

user2508758


1 Answers

You're looking for:

%s#\vl\=([0-9.]+)u\s+w\=([0-9.]+)u\zs.*#\=' r='.string(eval(submatch(1))/eval(submatch(2))).'u'

The important things are:

  • \= that tells you'll be inserting an expression -- the 3rd one (the first two are quirks induced by my use of very-magic regex with \v) -> :h :s\=
  • submatch() to access \1 and \2
  • eval() to convert the submatches into floating point numbers, and string() to convert it back
  • also note that in order to insert text after \=, you need to explicitly build a string

Then, I've used:

  • \v to simplify the regex,
  • :s# instead of :s/ to simplify the replacement expression as I need / to compute a division,
  • \zs to simplify the replacement expression as well.

Last need to know piece of information, to reach the documentation related to regex/pattern, prepend what you are looking for with a slash -> :h /\v, :h /\zs

like image 161
Luc Hermitte Avatar answered Sep 19 '22 04:09

Luc Hermitte