开发者

replace an expression of the form x*(string) with x copies of that string

开发者 https://www.devze.com 2023-02-18 03:50 出处:网络
I have some expressions of the form 3*(item1; item2; item3;), and I want to replace them with item1;item2;item3;item1;item2;item3;item1;item2;item3; (i.e. 3 lots of the thing in brackets, not includin

I have some expressions of the form 3*(item1; item2; item3;), and I want to replace them with item1;item2;item3;item1;item2;item3;item1;item2;item3; (i.e. 3 lots of the thing in brackets, not including the brackets)

I can write a regex to extract the relevant parts, but I'm not sure how to do the other part -- I had a play around with submatch() and eval() but I've not found a way to concatenate a string to itself a specific number of times:

:%s/\(\d+\)\*(\(\_[^)]\+\))/what goes here...?

I had hoped something like \2{\1} would work, but that doesn't evaluate the number in braces. If 开发者_C百科I'm going about this the wrong way that's fine -- I'm not particularly tied to doing it this way, it's just what I sort of know, and I just wondered if it was easily possible in Vim.

Thanks if anyone can help!


No need for custom function. You can use the built-in repeat() the same way.

%s#\v(\d+)\*\((\_[^)]+)\)#\=repeat(submatch(2), submatch(1))#gc

more info here :help repeat() and :help function-list for a list of built-in functions.


You could define a function that makes a repeated copy of a string ...

function! RepeatString(n,s)
  let l:result=""
  let l:n=a:n
  while l:n>0
    let l:result = l:result . a:s
    let l:n = l:n-1
  endwhile
  return l:result
endfunction

(note: this is very inefficient if n is large; it may well be that, e.g., making a list and calling join is more efficient) and then use the expression-evaluating feature of :s ...

:%s/\(\d\+\)\*(\([^)]\+\))/\=RepeatString(submatch(1),submatch(2))/g

(note: there are a couple of differences between my regexp and yours, which may be the results of typos in the original question).

0

精彩评论

暂无评论...
验证码 换一张
取 消