vim用数学表达式替换

时间:2016-06-14 07:19:38

标签: vim substitution

我需要更换以下行:

[rescap] l=1.2u w=1.5u 

通过

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

r 0.8k的值是l / w

我正在尝试使用vim(已在perl中完成但希望使用vim实现)

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

但它不评估表达式和打印:

  

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

如果我尝试评估表达式的\ =,则将l和w假设为变量并抛出错误。

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

我必须通过许多文件使用vim -s scriptfile运行上面的表达式。 只需要弄清楚上面的替换声明。

2 个答案:

答案 0 :(得分:3)

您正在寻找:

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

重要的是:

  • \=告诉你将插入一个表达式 - 第三个(前两个是我使用非常神奇的正则表达式\v引起的怪癖) - > :h :s\=
  • submatch()访问\1\2
  • eval()将子匹配转换为浮点数,将string()转换回来
  • 还要注意,为了在\=之后插入文本,您需要显式构建字符串

然后,我用过:

  • \v简化正则表达式,
  • :s#代替:s/来简化替换表达式,因为我需要/来计算分部,
  • \zs也可以简化替换表达式。

最后需要了解一些信息,以获取与正则表达式/模式相关的文档,使用斜杠添加您要查找的内容 - > :h /\v:h /\zs

答案 1 :(得分:2)

以下命令也将起作用:

s#\vl\=(\d+\.\d+)u w\=(\d+\.\d+)u#\=printf('%s r=%.1fk', submatch(0), str2float(submatch(1))/str2float(submatch(2)))  

一些解释:

  • submatch(0)将包含所有匹配的字符串
  • str2float()用于将字符串转换为浮点类型
  • printf()用于简化输出字符串格式的控制。