заменить выражение вида x * (строка) на x копий этой строки - PullRequest
0 голосов
/ 22 марта 2011

У меня есть некоторые выражения вида 3 * (item1; item2; item3;), и я хочу заменить их на item1; item2; item3; item1; item1; item2; item3; item1; item2; item3;(то есть 3 штуки в скобках, не включая скобки)

Я могу написать регулярное выражение для извлечения соответствующих частей, но я не уверен, как сделать другую часть - у меня была игравокруг с submatch () и eval (), но я не нашел способа объединить строку с собой определенное количество раз:

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

Я надеялся что-то вроде \2 {\ 1} будет работать, но это не оценивает число в фигурных скобках.Если я поступаю неправильно, это нормально - я не особенно привязан к тому, чтобы делать это таким образом, я просто знаю, и мне просто интересно, возможно ли это легко сделать в Vim.

Спасибо, если кто-нибудь может помочь!

Ответы [ 2 ]

0 голосов
/ 24 марта 2011

Нет необходимости для пользовательских функций.Вы можете использовать встроенные repeat() таким же образом.

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

подробнее здесь :help repeat() и :help function-list для списка встроенных функций.

0 голосов
/ 22 марта 2011

Вы можете определить функцию, которая делает повторную копию строки ...

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

(примечание: это очень неэффективно, если n большое; вполне может быть, например, созданиесписок и вызов join более эффективны), а затем используйте функцию оценки выражений :s ...

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

(примечание: между моим регулярным выражением и вашим есть несколько отличий, которыеможет быть результатом опечаток в исходном вопросе).

...