任何文本编辑器都可以用一些数学运算来替换文本吗?

任何文本编辑器都可以用一些数学运算来替换文本吗?

我有很大的 XML 文件

<obj param="2542">
<obj param="2333">
<obj param="6433">

我需要将所有“param”值增加某个数字。我可以在很多编辑器中使用正则表达式搜索匹配我需要的数字,但是如何将一些数学运算应用到替换中呢?

答案1

经过一番探索,我发现 vim 只需一个命令就可以完成此操作,无需编写脚本。例如,要将以下所有数字加 50,<obj param="您可以使用:

:%s@<obj param="\(\d\+\)@\='<obj param="' . (submatch(1) + 50)@g

让我来分析一下。

:是在 vim 中进入/表示命令行模式的一般方法。

%意味着在整个文档范围内;您可以输入一个数字范围,例如,1,50只在前 50 行内执行此操作。

s是 substitute 的简写(如果你愿意,你可以把整个单词写出来)

@是分隔符;您可以使用任何其他字符,只要它不在您要搜索的内容中即可。只需使用三次即可。(语法类似于sed.)

直到下一个分隔符 @ 出现为止的所有内容都是要搜索的正则表达式模式,在本例中,<obj param="后面跟着\d\+,即任意数量的数字。\(\)用于将整个数字序列设置为单个正则表达式组,该组将匹配反向引用\1,例如 或 vim 的submatch命令。

然后定界符标记@后面的内容为替换文本。

这里开头的意思\=是替换某些求值表达式的结果,而不是正则表达式模式或字符串,这才是关键。

然后我们有'<obj param="'替换文本的开头。.接下来是 vim 的连接字符串函数。

submatch(1)是 vim 内置函数,它只能在替换命令中使用,并返回与正则表达式相同的字符串\1;您可以将submatch(2)其用作正则表达式的等价物\2。 (\0是整个匹配的模式,但我们在这里不需要它。)搜索模式中的\(\)用于标记什么算作submatch(1)

因此,结果等于将搜索模式(submatch(1) + 50)后面的数字加上 50 。<obj param="

分隔符@再次用于标记替换文本的结束。

该标志g用于使替换全局化;如果您只想替换每行上的第一个实例,则可以省略此项。

您大概可以从那里算出如何对不同的数字进行加、减、除等等。

答案2

在 Emacs (自版本 23 起) 中:用于\,执行任意 Lisp 代码正则表达式替换例如,要计算数字的平方,可以使用

M-x replace-regexp
param="\([0-9]+\)"
param="\,(* \#1 \#1)"

在 Vim 中:用 开始替换文本\=(参见:help sub-replace-special)。例如,要计算数字的平方:

s!param="\([0-9]\+\)"!\='param="'.submatch(1)*submatch(1).'"'!

有几种编辑器允许您使用宏来做这类事情:定义一个宏,1. 查找下一个匹配项,2. 执行替换(必要时使用外部算术工具);只要有匹配项,就重复执行该宏多次。

答案3

你可以使用 vim 来帮你完成这个。只需打开你的文件并录制. 例如:搜索任意号码

/[0-9]{1,}

然后按 q 和 a(将宏存储在寄存器 a 中)。之后,按 Ctrl-X(将数字增加 1),然后按 n(获取下一个搜索结果)。完成后,再次按 q 保存宏。现在,您可以通过按 @+a 将宏应用于下一个数字。这将更改当前数字并跳转到下一个数字。通过重复该操作或使用 x@a,您可以重复该操作 x 次。

好吧,这个描述可能不足以说明如何做到这一点。只需参考描述 vim 中的宏机制的教程即可。

相关内容