4

我想用每行开头从 1 开始的递增索引的字符串替换每个子匹配,以便替换字符串为varargin{1}, varargin{2},varargin{3}等。对于更大的数字,数字字符串自然需要多个字符, eg: varargin{9}, varargin{10}, 等。输入数据为MATLAB代码;示例输入和所需输出如下所示。我主要是在寻找 Vim 解决方案,但也可以通过其他方式来实现这一点。

下面的正则表达式创建从 1 开始的运行索引,但每行都会更改:

:let @a=1 | %s/\v.*'\zs.*\ze\);/\=substitute(submatch(0), '\s[a-zA-Z0-9{}_.]*', ' varargin{'.(@a+setreg('a',@a+1)).'}', 'g')/g

我的问题是:

如何在每行的开头将索引重置为 1,并在每个子匹配之间将索引增加 1?

上面的代码是http://vim.wikia.com/wiki/Substitute_with_incrementing_numbers上的“用升序替换”示例的修改版本:

:let @a=1 | %s/abc/\='xyz_'.(@a+setreg('a',@a+1))/g

示例输入 #1:

messages.msg1.English = xprintf('analysis directory is on %s\n', analysis_dir);

例如输入 #1 的所需输出:

messages.msg1.English = xprintf('analysis directory is on %s\n', varargin{1});

示例输入#2:

messages.msg15.English = xprintf('the following sessions (%d pcs) have been approved: %s', handling_struct.n_of_accepted, handling_struct.accepted_sessions_vector);

例如输入 #2 的所需输出:

messages.msg15.English = xprintf('the following sessions (%d pcs) have been approved: %s', varargin{1}, varargin{2});

示例输入#3:

messages.msg19.English = xprintf('looking for files ''%s'' in %d separate dirs', give_file_struct.regex, number_of_dirs);

例如输入#3的所需输出:

messages.msg19.English = xprintf('looking for files ''%s'' in %d separate dirs', varargin{1}, varargin{2});
4

2 回答 2

4

在这种情况下,我会使用以下命令:

:g/^/let n=[0] | s/abc/\='xyz_'.map(n,'v:val+1')[0]/g

另请参阅对“<a href="https://stackoverflow.com/q/7366430/254635">如何在 Vim 中用编号标签替换 CSV 列分隔符?”问题的回答。

于 2012-11-11T18:45:38.713 回答
1

这可能是一个 hacky 解决方案,但如果我想在没有函数的情况下快速执行此操作,那么我会执行以下操作:

:let i=1<cr>                                         "set the index variable
qbf lcEvarargin{<C-r>=i<cr>},<esc>:let i+=1<cr>q     "record a macro
u                                                    "undo those changes
:%norm$F':let i=1<C-v><C-j>1000@b<cr>                "run the macro on each line
:%s/,$/);/<cr>                                       "clean up

请注意,我使用<>vim 中的符号来表示特殊键,因此<cr>表示回车并<C-r>表示 CTRL-R(请参阅 参考资料:h i_CTRL-R)。在命令行<C-v><C-j>中放入文字字符。^@这允许普通模式在不完成命令的情况下“按 Enter”。我:norm在这里使用宏而不是宏,因为当:norm抛出错误时,它只会移动到下一行。当宏抛出错误时(例如,ft当行中没有更多的 t 时尝试执行),那么它就完全失败了。这样我可以运行宏 1000 次,一旦失败就继续移动。同样,这可能不是最优雅的解决方案,但它确实有效,而且我的懒惰通常会胜出。

于 2012-11-11T18:01:01.433 回答