9

This question already has an answer here:

I'm trying to write a function that will delete each line that matches a pattern. But that pattern will change based on the words held in a list (made from a dictionary). I was thinking it would be a simple for loop but the for loop variable doesn't expand inside the pattern.

for key in sort(keys(myDict))
    %g/^The key/d
endfor

But the loop looks for ^The key instead of ^The red, ^The green, ^The blue, etc. It doesn't expand the key variable to whatever it's holding.

How can I use a variable inside a regex pattern and have the variable expand? Or is there a better way entirely of achieving my goal?

marked as duplicate by Martin Tournoij Mar 13 '16 at 3:36

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

10

You need to "build" your global command using :execute like so:

for key in sort(keys(myDict))
    execute '%g/^The ' . key . '/d'
endfor

See :h :exe for more help using :execute.

Some thoughts:

  • You may need to escaping your keys
  • Might consider alternation. e.g. \(red\|blue\|green\)
  • You may want to :delete into the black hole register to prevent any surprises. e.g. :d_
  • Perfect. This question doesn't require escaping inside of the variable but, just for completeness, how would one do that? Just use split on the variable and concatenate it back together into a new variable with escape characters where they are required? – embedded.kyle Mar 16 '15 at 22:05
  • 2
    The easiest way would be to use the \V or very non-magic along with the escape() function. e.g. let regex = '\V\^The \(' . join(map(keys(myDict), 'escape(v:val, '''\''')'), '\|') . '\)' – Peter Rincker Mar 16 '15 at 23:11

Not the answer you're looking for? Browse other questions tagged or ask your own question.