Monday, August 30, 2021

Re: How do I search and replace based on a list?

On 2021-08-28 03:05, Luciano ES wrote:
> So I would like to create a list of string pairs, ideally in a
> separate file and with some kind of separator such as '|' between
> the strings. Then I would highlight the line or paragraph and run
> the macro or script and have all pair replacements applied
> automatically.

If you're willing to keep it in a vim-script rather than an external
file, and you can identify your search-strings generically with a
regex, it's amazingly beautiful:

:%s/generic regex/\=get({'from1': 'to1', 'from2': 'to2', 'from3':
'to3'}, submatch(0), submatch(0))/g

where you only need to update that from→to dict.

If each is only a single word, that generic regex can be as simple as

:%s/\w\+/\=get({…}, submatch(0), submatch(0))/g

That dictionary doesn't *have* to be inlined, so you can create it
and maintain it dynamically:

:let b:mymap={'from1': 'to1', 'from2': 'to2', 'from3': 'to3'}

and then use

:%s/\w\+/\=get(b:mymap, submatch(0), submatch(0))/g

allowing you to dynamically update it

:let b:mymap['tim']='luciano'

and re-run the command to pick up the new substitution(s)

:%s/\w\+/\=get(b:mymap, submatch(0), submatch(0))/g

It can even be made into a mapping in your vimrc if you want easy
access to it rather than relying on your preserved command-history.

It also has the advantage that each item only gets substituted once.
For an example, imagine doing

%s/wasp/horsefly/g
%s/fly/gnat/g

you'd end up with a bunch of "horsegnats".

However, if you want, you can transform a pipe-delimited list
(assuming no crazy meta-chars) into commands that can then be
executed:

:%s@\(.*\)|\(.*\)@:%s/\1/\2/g

This mogrifies it into a list of :s commands. You can then yank them
all

:%y


At this point, you can either

:q!

to close that buffer discarding those modifications, or you can keep
them around and directly modify the list of substitute commands
directly rather than using an intermediate pipe-delimited form that
you need to transform every time.

Once you've yanked them into the scratch/unnamed register, you can
execute them as a macro

@"

However, beware the replacing-already-replaced-things issue mentioned
above.

Hope this helps,

-Tim


For more, you can read up at

:help get()
:help sub-replace-special
:help @

--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/vim_use/20210830082956.5e225016%40bigbox.attlocal.net.

No comments: